[React] 최적화와 메모이제이션
리액트 앱에서의 연산 최적화: 메모이제이션(Memoization) 기법 사용
-특정 입력에 대한 결과를 계산 -> 메모리 어딘가에 저장 -> 동일한 요청 들어오면, 저장한 결괏값을 빠르게 제공
-동적 프로그래밍 (DP)에서 사용
1. UseMemo
-결괏값 기억 -> 필요할 때 사용 -> 불필요한 함수 호출 막아줌
const value = useMemo(() => {
return count * count
}, [count])
=> 콜백함수 () => {}는, [count]의 값이 변하지 않는 한, 다시 호출되지 않음
2. React.memo
-컴포넌트가 불필요하게 리랜더링되는 것을 방지
-부모 컴포넌트에서 내려준 props가 변경되지 않는 한, 리랜더링되지 않음
export default React.memo(CompA);
=> ComA 컴포넌트는 어떤 상황에서도 리랜더링될 필요 없는 컴포넌트이므로, 위와 같이 감싸줌
(△맹점)
-부모 -> 자식에게 props로 내려준 값이 함수일 경우 : App.jsx가 리랜더링되면, 기존의 넘겨준 함수A와 받은 함수A는, 이름이 같을지라도 서로 다른 참조값을 가지게 됨. -> React.memo는 props가 변한 것으로 판단 -> React.memo로 감싸주었음에도, 컴포넌트 리랜더링 발생
(🙆♀️보완)
-useCallback을 사용 (컴포넌트를 리랜더해도, 함수를 다시 생성하지 않도록 만들어줌)
3. useCallback
-컴포넌트가 리랜더될 때, 내부에 작성된 함수를 다시 실행하지 않도록 메모이제이션하는 리액트 훅
const onCreate = useCallback(() => {
setState([newItem, ...state])
}, [])
=> 의존성 배열을 빈 배열로 지정했으므로, 콜백함수는 어떤 경우에도 다시 생성되지 않음 (컴포넌트가 리랜더될지라도)
(△맹점)
const onCrate = useCallback(() => {
setState([newItem, ...state])
}, [state])
=> [state]값이 업데이트됨 -> 함수 onCrate를 계속 재생성 -> useCallback 적용한 의미가 없음
(🙆♀️보완 : 함수형 업데이트 방법을 사용)
const onCreate = useCallback(() => {
setState((state) => [newItem, ...state])
}, [])
=> setState에 콜백함수를 전달
=> 함수형 업데이트 사용 : 항상 최신 State값을 매개변수로 저장 -> 콜백함수가 반환한 값은 새로운 state값이 되어 업데이트 됨
=> ∴useCallback을 사용하면서 + setState로 최신 state값을 추적하려면 : 함수형 업데이트 기능을 사용해야 함