본문 바로가기

Sparta x 이노베이션 캠프/React

TIL : useMemo, useEffect, useCallback 각 사용법, 차이

반응형

invalid Hook call 에러가 나는 원인에는 여러가지가 있는데 Hook에 대해 잘 모르는 상태로 쓸 때 에러 확률이 높다.

특히 커스텀 Hook을 만들어 사용할때!

Custom Hook을 쓰는 이유는 use로 시작하는 여러가지 Hook을 하나로 묶기 위함임.

 

useEffect 

목적 : 뭔가가 바뀌면 어떤 동작을 자동으로 실행하기 위해 사용한다.

인자 

인라인 콜백함수: 의존성 리스트에 있는 항목 중의 하나가 업데이트 되면 실행시킬 동작

의존성 리스트: 이 리스트에 있는 요소가 업데이트되면 콜백함수를 다시 작동.

useEffect(()=>{어떤 동작},[뭔가]);

사용  예

useState와 함께 사용하는 예시

const [ state, setState ] = useStae('idle'); //프로세스의 진행상태를 저장하는 state

useEffect(()=>{
	if(state ==== 'success'){ //state가 success일때만 if문이 실행.
    console.log("PROCESS DONE!! <<success>>");
    setState('idle'); //state를 초기상태로 돌려줌.
    }
},[state]); //프로세스가 idle -> pending -> success/fail로 바뀔 때 마다 UseEffect로 감싼 부분 실행.

* idle: 프로그램을 수행하지 않는 상태(프로세스가 아님) ex) I/O 인터럽트 대기중이거나 준비 큐에서 대기하거나 sleep하고 있거나....

 

useCallback

사용 목적

원하는 타이밍에 호출시킬 함수를 만들기 위해 사용(함수가 반환)

인자

인라인 콜백함수: 원하는 타이밍에 동작시킬 동작

의존성 리스트: 의존성에 포함된 요소가 업데이트 될 경우, 반환되는 함수도 갱신됨

 

사용 예

useEffect, useState와 함께 사용하는 예시

const [ food, setFood ] = useState('샐러드');
const [ menuAsked, setMenuAsked ] = useState(false);

useEffect(()=>{
	if(menuAsked === true){
    	printMenu();
        setMenuAsked(false); //state를 초기상태로 돌려줌.
    }
},[menuAsked])

const printMenu useCallback(()=>{
	console.log(`[Today's Dinner Menu : ${food}]`);
},[food]);

설명

menuAsked의 상태가 바뀔때마다 useEffect의 인라인 콜백함수가 실행되고, menuAsked의 상태가 true라면 printMenu 함수가 호출된다. 코드가 실행되는 동안 food의 상태가 바뀌지 않는다면 printMenu 함수의 내용도 바뀌지 않음.

동작 food menueAsked printMenu 함수 변화 출력
최초 상태 '샐러드' false x -
setFood('고추장 삼겹살') '고추장 삼겹살' false o -
setFood('갈치구이') '갈치구이' false o -
setMenueAsked(true) '갈치구이' true x [Today's Dinner Menu: 갈치구이]

useMemo

사용 목적 

useCallback은 원하는 타이밍에 실행시킬 함수를 만드는데 사용

그에 비해 useMemo는 원한느 값을 업데이트하기 위해 사용

 

인자

인라인콜백

의존성 리스트: 이 배열이 없으면 렌더링마다 새 값을 계산함.

사용 예

const person = useMemo(
	()=>(
    	<Person 
        name={name}
        song={favoriteSong}
        />
    ),
    [name, favoriteSong]
);
  • name, favoriteSong이 바뀌면 값을 새로 계산.
  • name, favoriteSong이 바뀌지 않으면 값을 새로 계산하지 않고 기억해두었던 이전의 값을 사용
  • 렌더링 중에 실행됨
  • useMemo를 사용하지 않아도 코드가 동작해야하며, 쓸데없는 리렌더를 줄이기 위해 사용(최적화)

 

useEffect vs  useCallback

useEffect어떤 값의 변화가 동작을 자동으로 불러오도록 하고 싶을때,

useCallback은 어떤 값이 변했을때 특정 동작을 값에 따라 다르게 실행시키고 싶거나 원하는 타이밍에 어떤 동작을 실행시키고 싶을때 적합하다.

State를 바라보고 있다가 effect를 주는 것인데 이때의 effect는 멱등성이 유지된다.

그에 비해 useCallback은 state에 따라 다른 동작을 하는 함수를 리턴할 수 있으므로 동작을 state에 따라 다르게 주고 싶을때 유용.

useMemo는 값을 리턴하며, 최적화에 방점이 찍힌다.

 

추가

useState와 useMemo의 사용처 비교

useState를 쓸 수 밖에 없는 상황을 제외하고는 useMemo로 감싼 const로 선언하여 사용하는 것이 좋다.

아래처럼 의존성에 따라 값이 자동적으로 바뀌는 경우엔 useState를 사용할 이유가 없다.(자동갱신에 가까움)

//b와 c를 더한 값이 a가 되는 경우
const a = useMemo(()=>{b+c}, [b,c]);

그러나 아래의 경우처럼 server에서 값을 받아오거나 사용자로부터 입력을 받는 경우(onChange마다 변경이 일어남)에는 useState를 사용한다.

// useState를 쓸 수 밖에 없는 상황
const [name, setName] = useState('');
const [email, setEmail] = useState('');
(생략)
// 1. get data from server
fetch(domain).then((res) => setName(res.data.name));
(생략)
// 2. get data from user input
return(
	<Form>
    		<label css={labelStyle} htmlFor="email"> Email </label>
		
		<input
        	type='email'
                id='email'
                value={email}
                (...)
                onChange={(event) => setEmail(event.currentTarget.value)}
        />
    </Form>
)

 

 

 

Reference

본문 발췌 from

https://intrepidgeeks.com/tutorial/usage-and-differences-of-hook-useeffect-usememoand-usecallback

 

[Hook] useEffect, useMemo 그리고 useCallback 각 사용법과 차이

Invalid Hook call 에러가 나는 원인에는 여러가지가 있는데, Hook에 대해서 잘 모르는 상태로 썼을때 에러가 날 확률이 높아진다. 특히 커스텀 Hook을 만들어 사용할때 이런 개념들을 모르고 쓰면 코드

intrepidgeeks.com

 

반응형