리액트는 어떻게 객체들을 비교할까요?
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
다음과 같은 결과가 나타나는 이유가 무엇일까요?
일단 함수 컴포넌트는 리렌더링 될 때마다 항상 함수가 전체가 실행된다는 것을 염두에 두고 생각을 해보면 좋을 것 같습니다.
useEffect
에 의해 setName이 비동기적으로 예약이 되고 "num"
, "onlynumber"
가 콘솔에 찍힙니다.setName
이 실행되면서 name이 바뀌었기 때문에 컴포넌트가 다시 리렌더링 됩니다. onlyNumber
와 onlyObj
의 선언 및 할당이 되고useEffect
는 mount될 때만 실행이 되게끔 되어 있으니 그냥 넘어가고useEfeect
는 본래 가지고 있던 onlyNumber
와 현재의 onlyNumber
가 같은 값을 가지므로 실행되지 않습니다.useEffect
는 조금 다릅니다. 첫번째 onlyObj
도 빈 객체이고 새로이 선언 할당된 onlyObj
도 빈 객체인데 세번째 useEffect
는 실행이 되었을까요? 이건 React가 성능 향상을 위해 객체를 비교할때 얕은 비교를 하기 때문입니다. 객체가 참조하는 주소값이 바뀌었는지만 비교하게 되니 새로이 선언 할당된 onlyObj
는 이전 onlyObj
는 다른 값으로 판단되어 useEffect
가 실행된 것입니다.