08_Oct_2021 ๐Ÿฐ์—˜๋ฆฌ์Šค AI ํŠธ๋ž™ TIL: React Hooks

์œ ํ™˜์ตยท2021๋…„ 10์›” 9์ผ
0

Hooks๋ž€?

์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌ(State)ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์ƒํ˜ธ์ž‘์šฉ(Effect)์„ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
useState ๋˜ํ•œ State Hook์ด๋‹ค.

๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

๊ธฐ์กด์—๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ State์™€ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด, ๋ฐ˜๋“œ์‹œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋‚˜, ๊ฐœ๋ฐœ์ž๊ฐ€ ๋Š๋ผ๊ธฐ์— ๋ณต์žกํ•œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์™„ํ•˜๊ณ  ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด React 16.8 ๋ฒ„์ „์— ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

์œ ์˜์‚ฌํ•ญ

const App = () => {
	const [username, setUsername] = useState('');
    	return (
        	<div>
            		<h1>{username}๋‹˜ ์–ด์„œ์˜ค์„ธ์š”.</h1>
           	</div>
        );
};
  • Hook์€ React ํ•จ์ˆ˜ (์ปดํฌ๋„ŒํŠธ, Hook) ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • Hook์˜ ์ด๋ฆ„์€ ๋ฐ˜๋“œ์‹œ 'use'๋กœ ์‹œ์ž‘ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ตœ์ƒ์œ„ Level์—์„œ๋งŒ Hook์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค (if๋ฌธ ํ˜น์€ for๋ฌธ, ์ฝœ๋ฐฑํ•จ์ˆ˜ ๋‚ด์—์„œ ํ˜ธ์ถœ ๊ธˆ์ง€)

State Hook๊ณผ Effect Hook

State Hook

const App = () => {
	//์ผ๋ฐ˜์ ์ธ useState ์‚ฌ์šฉ๋ฒ•
    const [state์ด๋ฆ„, setState์ด๋ฆ„] = useState(์ดˆ๊ธฐ๊ฐ’)
    // Array๊ฐ€ ๋ฐ˜ํ™˜๋˜๊ณ , 0๋ฒˆ์งธ ๊ฐ’์€ ํ˜„์žฌ๊ฐ’, 1๋ฒˆ์งธ๋Š” ๊ฐ’์„ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•œ ๋˜๋‹ค๋ฅธ ํ•จ์ˆ˜
    // ์ฆ‰, Hooks๋Š” ํ•จ์ˆ˜ ์ชผ๊ฐ€๋ฆฌ์ด๋‹ค.
}
  • useState๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด ๋™์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” hook
  • ์ตœ์ดˆ์— useState๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ, ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์„ค์ •๋˜๊ณ  ์ดํ›„ ์žฌ ๋ Œ๋”๋ง์ด ๋  ๊ฒฝ์šฐ ๋ฌด์‹œ๋œ๋‹ค.
  • state๋Š” ์ฝ๊ธฐ ์ „์šฉ์ด๋ฏ€๋กœ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋ฉด ์•„๋‹ˆ๋œ๋‹ค.
  • state๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” setState๋ฅผ ์ด์šฉํ•œ๋‹ค.
  • state๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ์ž๋™์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ ๋ Œ๋”๋ง๋œ๋‹ค.
    => setStateํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ state ๊ฐ’์„ ๋ณ€๊ฒฝํ•จ๊ณผ ๋™์‹œ ๋ณ€๊ฒฝ์ด ๋˜์—ˆ์Œ์„ react์˜ core์— ์•Œ๋ ค์ฃผ๋Š” ๋กœ์ง์ด ๋งˆ์ง€๋ง‰์— ํ˜ธ์ถœ๋˜๊ณ  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋จ.
const App = () => {
	const[title, setTitle] = useState('');
  
    // State๋ฅผ ๋ณ€๊ฒฝํ•  ๊ฐ’์„ ์ง์ ‘ ์ž…๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•
   	setTitle('Hello');
  
    //ํ˜„์žฌ ๊ฐ’์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜ ์„ ์–ธ -> return ๊ฐ’์ด state์— ๋ฐ˜์˜
    	setTitle((current)=>{
        	return current + 'world'l
        })
}
  • state๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋Š” setStateํ•จ์ˆ˜์— ์ง์ ‘ ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๊ฑฐ๋‚˜,
  • ํ˜„์žฌ ๊ฐ’์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. ์ด ํ•จ์ˆ˜์—์„œ return ๋˜๋Š” ๊ฐ’์ด state์— ๋ฐ˜์˜๋œ๋‹ค.

Effect Hook

const App = () => {
	useEffect(EffectCallback, Deps?)
}
  • Effect Hook์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ side effect๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ดˆ๋กœ ๋ Œ๋”๋ง ๋  ๋•Œ, ์ง€์ •ํ•œ State๋‚˜ Prop์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ดํŽ™ํŠธ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
    EffectCallback: Deps์— ์ง€์ •๋œ ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜
    Deps: ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•  ๋ณ€์ˆ˜๋“ค์˜ ์ง‘ํ•ฉ (๋ฐฐ์—ด)
const App = () => {
	const [count, setCount] = useState(0)
    
    useEffect(() => {
    	console.log(`๋ฒ„ํŠผ์„ ${count}ํšŒ ํด๋ฆญํ–ˆ์Šต๋‹ˆ๋‹ค.`)
    }, [count])
    
    return (
    	<div>
            <button onClick={()=> setCount(count + 1)}>
            ํด๋ฆญํ•˜์„ธ์š”
            </button>
        </div>
    );
}
const App = () => {
	useEffect(()=>{
    	//state๊ฐ€ ๋ณ€๊ฒฝ ๋  ๋•Œ, ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ ์‹คํ–‰
    	const intervalId = setInterval(()=>{
        	console.log('์•ˆ๋…•ํ•˜์„ธ์š”');
        },1000);
        
        // ์ปดํฌ๋„ŒํŠธ๋ฅผ ์žฌ ๋ Œ๋”๋ง ํ•˜๊ธฐ ์ „์—, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—†์–ด์งˆ ๋•Œ ์‹คํ–‰
        return () => {
        	clearInterval(intervalId);
        }
    }, []) // ์—†๋”๋ผ๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ์ด ๋  ๋•Œ ํ•œ๋ฒˆ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—
    	    //์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ, ํ•œ๋ฒˆ๋งŒ ์‹คํ–‰ํ•˜๋ผ๋Š” ์˜๋ฏธ
}

useEffect์˜ ์ดํŽ™ํŠธ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ returnํ•  ๊ฒฝ์šฐ state๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ธฐ ์ „๊ณผ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—†์–ด์งˆ ๋•Œ (Destroy) ํ˜ธ์ถœํ•  ํ•จ์ˆ˜๋ฅผ ์ง€์ •ํ•œ๋‹ค.

์ด์™ธ์˜ Hooks

useMemo

const momoizedValue = useMemo(()=> computeExpensiveValue(a,b), [a,b])
const App = () => {
	const [firstName, setFirstName] = useState('Alex');
    const [lastName, setLastName] = useState('Yoo');
	
    //์ด๋ฆ„๊ณผ ์„ฑ์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ํ’€๋„ค์ž„์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•จ
    const fullName = useMemo(()=> {
    	return `${firstName} ${lastName}`;
    }, [firstName, lastName])
}
  • ์ง€์ •ํ•œ State๋‚œ Props๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐ’์„ ํ™œ์šฉํ•ด ๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜์—ฌ ์žฌ๋ Œ๋”๋ง ์‹œ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ธ๋‹ค.
  • useMemo์˜ ์—ฐ์‚ฐ์€ ๋ Œ๋”๋ง ๋‹จ๊ณ„์—์„œ ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๋กœ์ง์„ ์ž‘์„ฑํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋œ๋‹ค.

useCallbak

const momoizedCallback = useCallback(
	() => {
		doSomething(a,b);
	},
    [a,b],
);
const App = () => {
	const [firstName, setFirstName] = useState('Alex');
    const [lastName, setLastName] = useState('Yoo');
	
    //์ด๋ฆ„๊ณผ ์„ฑ์ด ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ํ’€๋„ค์ž„์„ returnํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜
    const getfullName = useCallback(()=> {
    	return `${firstName} ${lastName}`;
    }, [firstName, lastName])
    return <>{getFullName()}</>
}
  • ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜๋Š” Hook. ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋  ๋•Œ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ํ•จ์ˆ˜๊ฐ€ ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
  • useMemo(()=> fn, deps) === useCallback(fn, deps)

useRef

const refContainer = useRef(initialValue);
const App = () => {
	const inputRef = useRef(null)
    const onButtonClick = () => {
    	inputRef.current.focus();
    }
    return (
    	<div>
  	   <input ref={inputRef} type='text'/>
  	   <button onClick={onButtonClick}>
            input์œผ๋กœ ํฌ์ปค์Šค
  	   </button>
  	</div>
    );
};
  • ์ปดํฌ๋„ŒํŠธ ์ƒ์•  ์ฃผ๊ธฐ ๋‚ด์—์„œ ์œ ์ง€ํ•  ref ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ref ๊ฐ์ฒด๋Š” .current๋ผ๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ , ๊ทธ ๊ฐ’์„ ์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ React์—์„œ DOM Element์— ์ ‘๊ทผํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • useRef์— ์˜ํ•ด ๋ฐ˜ํ™˜๋œ ref ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋˜์ง€ ์•Š๋Š”๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ Hook

custom Hook

์‚ฌ์šฉ์ž ์ž„์˜์˜ Hook์„ ๋งŒ๋“ค๋ฉด ์ปดํฌ๋„ŒํŠธ ๋กœ์ง์„ ํ•จ์ˆ˜๋กœ ๋ฝ์•„๋‚ด์–ด ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
UI ์š”์†Œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ์„ ์˜ฌ๋ฆฌ๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ, ๋กœ์ง์˜ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด์„œ๋Š” Custom Hook์„ ์ œ์ž‘ํ•œ๋‹ค.

 function useMyHook(args){
  const [status, setStatus] = useState(null);
  // custom logic
  return status;
 }
  • ํ•œ ๋กœ์ง์ด ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉ๋  ๊ฒฝ์šฐ ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Hook์„ ๋งŒ๋“œ๋Š” ๊ฐœ๋…์ด๋‹ค.
  • Hook์˜ ์ด๋ฆ„์€ 'use'๋กœ ์‹œ์ž‘ํ•ด์•ผ ์ปจ๋ฒค์…˜์— ๋งž๋‹ค.
  • ํ•œ Hook ๋‚ด์˜ state๋Š” ๊ณต์œ ๋˜์ง€ ์•Š๋Š”๋‹ค.

ํ•œ์ค„ ํ‰: ๋ฆฌ์•กํŠธ ์ตœ์‹  ๋ฌธ๋ฒ•์—์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ธ React Hooks ์˜ ๊ฐœ๋…๊ณผ ์ข…๋ฅ˜์— ๋Œ€ํ•ด ๋ฐฐ์› ๊ณ  ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์žˆ์–ด ์ต์ˆ™ํ•ด์ง€๋Š” ์œ ์ตํ•œ ์‹œ๊ฐ„.

profile
์‚ฌ์šฉ์ž์˜ ํŽธ์˜๋ฅผ ๋” ์ƒ๊ฐํ•˜๊ณ  ํŽธ์•ˆํ•œ UI/UX ๊ฐœ๋ฐœ์„ ๊ฟˆ๊พธ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ง€๋ง์ƒ์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€