리액트는 객체 비교를 어떻게 할까?

엄강우·2022년 6월 9일
0

You don't know React

목록 보기
1/9

리액트는 어떻게 객체들을 비교할까요?

const Component = () => {
  const [, setName] = useState(1)

  const onlyNumber = 1
  const onlyObj = {}

  useEffect(() => {
    setTimeout(() => {
      setName((prev) => prev + 1)
    }, 100)
  }, [])

  useEffect(() => {
    console.log('num')
  }, [onlyNumber])

  useEffect(() => {
    console.log('obj')
  }, [onlyObj])
  return (/* 리턴 값 */)
}

다음 코드의 결과는 어떻게 될까요?

결과

num
obj
obj

다음과 같은 결과가 나타나는 이유가 무엇일까요?

일단 함수 컴포넌트는 리렌더링 될 때마다 항상 함수가 전체가 실행된다는 것을 염두에 두고 생각을 해보면 좋을 것 같습니다.

  1. Component 함수가 첫번째로 실행이 될때 첫 useEffect에 의해 setName이 비동기적으로 예약이 되고 "num", "onlynumber"가 콘솔에 찍힙니다.
  2. setName이 실행되면서 name이 바뀌었기 때문에 컴포넌트가 다시 리렌더링 됩니다.
  3. Component 함수가 두번째로 실행이 되면 이제 첫번째와 상황이 조금 다릅니다.
    • 일단 onlyNumberonlyObj의 선언 및 할당이 되고
    • 첫번째 useEffect는 mount될 때만 실행이 되게끔 되어 있으니 그냥 넘어가고
    • 두번째 useEfeect는 본래 가지고 있던 onlyNumber와 현재의 onlyNumber가 같은 값을 가지므로 실행되지 않습니다.
    • 세번째 useEffect는 조금 다릅니다. 첫번째 onlyObj도 빈 객체이고 새로이 선언 할당된 onlyObj도 빈 객체인데 세번째 useEffect는 실행이 되었을까요? 이건 React가 성능 향상을 위해 객체를 비교할때 얕은 비교를 하기 때문입니다. 객체가 참조하는 주소값이 바뀌었는지만 비교하게 되니 새로이 선언 할당된 onlyObj는 이전 onlyObj는 다른 값으로 판단되어 useEffect가 실행된 것입니다.
profile
안녕하세요 프론트엔드 개발자를 꿈꾸는 엄강우입니다.

0개의 댓글