React.memo
state 변경으로 인해 부모 컴포넌트가 재실행 될경우
해당 컴포넌트의 모든 하위 컴포넌트가 DOM 변경과 관련없이 재실행된다. (console.log로 확인 가능)
이때 하위 컴포넌트들의 필요없는재실행을 막기위해 React.memo를 사용할 수 있다.
아래와 같이 export할 때 감싸주면 된다.
React.memo는 함수형 컴포넌트에서만 사용할 수 있고
해당 컴포넌트에게 넘어오는 props를 확인해 props의 값 변경이 없다면 ( === 사용 )
ReactDOM은 해당 컴포넌트를 재실행 하지 않는다.
이처럼 React.memo는 최적화를 위해 사용하는데 남용하면 오히려 비용이 더 많이 들게된다.
이는 App 컴포넌트가 변경될 때마다 해당 컴포넌트 기존 props와 새로운 props의 값을 비교하기 때문인데
기존의 props 값도 저장해야하고 비교도 해야한다.
props 비교에 ===를 사용하기 때문에 배열, 함수와 같은 object는 절대 true가 나오지 않는다.
이때는 useCallback을 사용할 수 있다.
useCallback
부모의 컴포넌트에서 state가 바뀌었을 때,
부모 컴포넌트가 함수를 내부에서 정의해서 자식 컴포넌트에게 props로 주는 경우
부모 컴포넌트가 재실행될 때마다, 함수는 새로 정의해서 주게된다. (메모리 주소가 다름)
이로 인해 자식 컴포넌트의 리렌더링이 발생하게된다.
useCallback은 특정 함수를 전반적인 컴포넌트 실행에 있어서 따로 저장할 수 있게 해준다.
그리고 해당 객체의 재사용을 보장한다. useCallback의 사용법은 useEffect와 크게 다르지 않다.
useCallback의 두번째 인자로 배열을 넘겨주는데 배열 내부 변수의 값이 변경되었을때
useCallback은 useEffect와 같이 함수를 재정의 한다.
이때, 만약 useCallback의 dependancy로 allowToggle이 주어지지 않는다면
화면에서 아무리 Allow Toggling 버튼을 눌러도 paragraph는 toggle되지 않을 것이다.
이는 자바스크립트는 함수형 언어이고 함수형 언어의 특징인 Closure 때문이다.
중첩된 함수가 외부에서 정의된 변수를 사용할 때
함수가 정의 될 시기의 기준으로 lexical scope을 기억하게 된다.
이는 함수가 어디서 언제 호출되든 항상 같은 아웃풋을 생성하기 위함이다.
그런데 여기서 allowToggle은 상수로 정의되어 있으니 dependancy를 통해 함수를 재정의 하는 것이다.
Closure를 활용하면 useState를 약식으로 구현할 수 있다.
useMemo
useMemo의 첫번째 인자로 익명함수를 넘겨주는데 이때 저장하고 싶은 배열을 반환했고
두번째 인자로는 빈 배열을 넣었다.
useMemo를 통해 정렬된 배열을 메모리에 저장해서 사용하고
React.memo를 통해 props가 변경될 때만 UseMemoList가 실행된다.
이렇게 useMemo와 useCallback을 통해 props의 값이 진짜로 바꼈을 경우에만 리렌더링을 시킬 수 있다.
useMemo를 통해 값을 memoization하고
useCallback을 통해 함수를 memoization한다.
추가메모
setState함수의 호출로 state의 update를 schedule한다.
1. schedule
2. state update
3. component rerun
state batch
여러 state의 변경할 때 state의 변경의 순서는 보장되지만 immediate update는 보장되지 않는다.
여러 state의 변경이 schedule 되면 나중에 한번에 바꿈. (callback이나 promise가 없는 경우)
state 값은 해당 함수가 실행될 때를 기준으로 받아오는데 setState 함수로 값 변경을 했지만
해당 state를 사용할 때 변경전 state 값을 사용하게 될 수 있다.
함수가 기존의 props 값을 사용한다면 함수형태를 사용한 state update가 권장된다.
어떤 state 변경을 보장받고 싶은경우 : (show) => !show
'Javascript > React' 카테고리의 다른 글
[React] map() 관련 번들 사이즈 줄이기 (0) | 2024.07.07 |
---|---|
[React] React Conference 2024 정리 (0) | 2024.05.20 |
[React] Custom Hooks (0) | 2023.09.18 |