리렌더링이 일어난다는것은, App함수가 한번 더 호출된다는 의미이다. 아래 코드에서는 useState에 빈 배열이 전달 될때 1번, setData(initData)할때 두번 리랜더링이 된다. 그러면 함수 안의 계산들이 한번 더 이루어지는 것이다. 이 계산들을 리랜더링 될때마다 하지 않고 저장해두었다가 사용할 수 있도록 하는것이 useMemo이다.
function App(){
const [data,setData] = useState([]);
const getData = async()=>{
...
setData(initData);
}
return(...);
}
결과를 저장해서 사용하고싶은 계산로직을 useMemo를 이용한다. 한가지 주의할 점은 , useMemo를 통해 리턴된 값은 함수가 아니라는 점이다. 따라서
getDiaryAnalysis(); 이렇게 호출하면 안된다. 함수가 아니라 값으로 사용해야한다.
const getDiaryAnalysis = useMemo(() => {
console.log("일기 분석 시작 ");
const goodCount = data.filter((it) => it.emotion >= 3).length;
const badCount = data.length - goodCount;
const goodRatio = (goodCount / data.length) * 100;
return { goodCount, badCount, goodRatio };
}, [data.length]);
//배열에 data.length값이 들어갔다면, data.length가 변화할때만 연산을 다시 수행한다는 의미이다.
const value= useMemp(연산콜백함수,배열)
이렇게 코드를 쓰면, 얕은비교가 일어나 obj.count의 값이 다르다고 판단되어 리랜더링이 일어나게 된다.
const CounterB = React.memo(({ obj }) => {
useEffect(() => {
console.log(`CounterB Update - count : ${obj.count}`);
});
return <div>{obj.count}</div>;
});
React.Memo 사용코드
const CounterB = React.memo(({ obj }) => {
useEffect(() => {
console.log(`CounterB Update - count : ${obj.count}`);
});
return <div>{obj.count}</div>;
});
const areEqual = (prevProps, nextProps) => {
if (prevProps.obj.count === nextProps.obj.count) {
return true; // 이전 프롭스와 현재 프롭스가 같다.- > 리랜더링을 일으키지 않는다.
}
return false; // 래린더링을 일으킨다.
};
const MemoizedCounterB = React.memo(CounterB, areEqual);
return(
...
<MemoizedCounterB obj={obj} />
);