최적화 되어야 할 부분을 어떻게 찾지?
React development tools > components 탭 > 렌더할때 하이라이트 기능 켜기 > 어디서 변화가 일어나는지 찾기 쉽다 !
오늘의 최적화 : 일기를 하나 삭제했을 때 > 일기 작성 컴포넌트도 깜빡임
(그럴 필요가 전~혀 없는데??)
렌더링은 언제 일어날까?
- 본인이 가진 스테이트가 변경될 때
- 자신이 받은 프롭이 변경될 때
- 부모가 리랜더링 되었을 때
일기를 작성하여 저장하는데 작성 컴포넌트가 왜 리렌더링 될까?? 그것은 바로 작성 컴포넌트에서 받고 있는 onCreate 함수 때문!
[DiaryEditor.js]
코드가 긴 전체 컴포넌트를 React.memo로 감쌀 경우 -> export default 하는 부분을 전체 감싸주는 것도 가능!
export default React.memo(DiaryEditor)
[Simple.js]
onCreate 함수는 일기 저장시 데이터에 아이템 추가하는 역할을 한다
[DiaryEditior.js] 에서 useEffect로 컴포넌트가 언제 렌더되는지 확인해보자
총 두번 발생하는 것을 확인할 수 있다 (왜?? 부모컴포넌트 -> 초기 데이터 스테이트 초기값이 빈값인 상태로 처음 랜더링이 일어나고 (빈배열상태) -> getData 하여 값을 가져오면 데이터 스테이트가 한번 더 바뀌게 된다
그렇다면 그냥 onCreate 함수를 react.memo로 감싸면 되는 것 아닌가?!?!
아니다!!! onCreate 함수가 참조하는 것은 비원시 타입으로 얕은 비교를 함으로 react.memo로 할 수 없다!
oncreate 함수를 react.memo로 감싸게 된다면 만들어질때마다 리렌더 될 수 밖에 없다! simple 컴포넌트가 재생성될때마다 리렌더링 계속 될 것이다!
-> oncreate 함수가 재생성 안되어야! 에디터 컴포넌트 리렌더 막을 수 있으며 최적화가 가능하다 !!!
그럼 어떻게 하지?? useMemo (함수가 반환하는 값을 다시 사용할 수 있도록 의존성 배열을 기준으로) 를 사용해볼까??
사용하면 안된다!!! 함수 반환이 아니라 값을 반환하기 때문이다
우리가 원하는 것은? oncreate 함수 그잡채를 반환하는 것이지 값이 아니다!
-> useCallback이 답이다! (메모이제이션된 콜백을 반환한다,,,의존성 배열 값이 변하지 않으면 첫번째 인자로 전달한 콜백함수를 재사용 할 수 있도록 도와준다)
[Simple.js]
onCreate 함수를 useCallback으로 감싸보자 (일단은 의존성 배열은 빈값으로)
일기를 작성해보면 있엇던 데이터들이 없어지고 만든 일기 하나만 남는다
왜냐하면 의존성배열에 아무값도 없어서 그런 것이다
맨 처음에 oncreate 함수가 만들어지는 것은 빈 배열을 기준으로 처음 만들어진다
그렇다면 의존성 배열에 data 를 넣어볼까??
그래도 안된다! 이렇게 작성하면 우리가 원하는대로 작동하지 않는다!
우리는 데이터 스테이트가 변해도 재생성되지 않기를 바라는 것이다
재생성되지 않으면서 최신값을 어떠케 참조하지?? 함수형 업데이트를 활용하자!!!
setData (()=>{}) 콜백함수를 전달해보자 ((data) => [newItem, ...data])
상태변화 함수에 함수를 전달하는 것 = 함수형 업데이트 (의존성 배열을 비워놔도 인자를 참고하여 최신 데이터 참조한다)
이로써 일기를 작성할 때 작성 컴포넌트가 재렌더링 되는 것을 막을 수 있었다
정리해보자면
최적화를 위해 어떠한 기능을 수행하는 데 있어 불필요한 렌더링이 발생하는 부분이 있는지 확인해보자 (React Development tools)
불필요한 재렌더링을 유발하는 원인을 찾는다
값이라면 useMemo / 함수 그 자체를 반환해야 하는 경우 useCallback 으로 감싸준다