리액트는 Object.is
로 값을 비교한다.
따라서 함수를 프롭스로 전달하면, 참조가 달라서 다른 값으로 여겨진다.
아래와 같은 구조가 있다고 해보자.
const ParentComponent = () => {
const handleChild = () => {...}
return <ChildComponent 프롭스로받은함수={handleChild}/>
}
//
const ChildComponent = ({프롭스로받은함수}) => {
useEffect(() => {
프롭스로받은함수()
}, [프롭스로받은함수]);
return <div>ㅎㅇ</div>
}
이때, 부모컴포넌트에서 리렌더가 발생하면, 자식컴포넌트도 당연히 리렌더 된다.
이를 원치 않아서 React.memo로 props가 바뀌었을때만 리렌더 하고싶을 수 있음.
const ChildComponent = React.memo(({프롭스로받은함수}) => {
useEffect(() => {
프롭스로받은함수()
}, [프롭스로받은함수]);
return <div>ㅎㅇ</div>
});
//디버깅 목적용 네이밍. memo를 사용하면 이름이 사라져서 eslint 경고발생. forwardRef도 마찬가지다.
ChildComponent.displayname = 'ChildComponent'
이렇게 메모를 해도...함수는 객체라서 다른값(참조)이 되버린다!
결국 함수를 props로 받아올땐 useCallback
을 이용하여 감싸서 자식에게 전달해주어야 한다.
끝!