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

JueunPark·2022년 1월 21일
14

React

목록 보기
2/2
post-thumbnail

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

  • Custom Hook을 쓰는 이유: use*로 시작하는 여러가지 Hook을 하나로 묶기 위해

그러면 useEffectuseMemo, useCallback의 차이를 알아보고 적재적소에 활용하여 에러를 마주칠 확률을 낮춰보자.

1️⃣ useEffect

사용목적

  • 뭔가가 바뀌면 어떤 동작자동으로 실행하기 위해 사용
  • 인자
    • 인라인 콜백함수: 의존성 리스트에 있는 항목 중의 하나가 업데이트 되면 실행시킬 동작
    • 의존성 리스트: 이 리스트에 있는 요소가 업데이트되면 콜백함수를 다시 작동시킨다.
useEffect(() => {어떤 동작}, [뭔가]);

사용예시

  • useState와 함께 사용하는 예시
const [ state, setState ] = useState('idle'); // 프로세스의 진행상태를 저장하는 state

useEffect(() => {
	if (state === 'success'){ // state가 success일때만 if문이 실행된다.
    	console.log("PROCESS DONE!! <<success>>");
        setState('idle'); // state를 초기상태로 돌려준다.
    }
}, [state]); // 프로세스가 idle -> pending -> success/fail로 바뀔 때마다 useEffect로 감싼 부분이 실행된다.
  • 설명
    • state는 코드는 프로세스가 진행됨에 따라 idle, pending, success or fail로 업데이트 된다. 상태가 없데이트 될때마다 useEffect에 전달한 콜백함수가 실행이 되는데, 내부에 if문이 있기 때문에 console.log가 되는 것은 success일때 뿐이다.

idle이 뭔지 모른다면 참고

2️⃣ 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 함수의 내용도 바뀌지 않는다.
동작foodmenuAskedprintMenu 함수 변화출력
최초 상태'샐러드'falseX-
setFood('고추장 삼겹살')'고추장 삼겹살'falseO-
setFood('갈치 구이')'갈치 구이'falseO-
setMenuAsked(true)'갈치 구이'trueX[ Today's Dinner Menu : 갈치 구이 ]
  • setMenuAsked를 사용하면 menuAsked의 상태는 true가 되지만, 메뉴를 프린트 한뒤에는 다시 false로 초기화 된다.
  • setFoodprintMenu 함수에만 영향을 주고 setMenuAsked는 메뉴의 출력에만 관여한다.

3️⃣ 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는 멱등성이 유지된다.

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

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

  • 처음 React를 공부하기 시작했을때 용도가 비슷해보이는 것이 여러개 있어 어떤 때에 무엇을 써야할 지 몰랐는데, 사용하다보니 필요한 곳을 알게되는 것 같다. useEffect, useCallback, useMemo도 글로 이해하려는 것보다는 계속해서 사용해보고 예시를 많이 보는게 이해가 빠르게 될 것 같다.

🚨 추가

useStateuseMemo의 사용처 비교

  • 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>
)
profile
노트정리

1개의 댓글

comment-user-thumbnail
2023년 4월 2일

도움이 많이 되었습니다. 감사합니다!

답글 달기