DiaryApp - useContext()로 Props Drilling 방지해보기 - (2)

dobyming·2023년 2월 6일
0

React Study

목록 보기
11/13

useContext로 상태관리 함수 리팩토링하기

이전 포스팅 에 이어서 상태관리 함수들을 useContext()로 관리해봅시다.

1. 상태관리 함수용 Context export 하기

export const DiaryDispatchContext = React.createContext(); 

2. return 부에 Context 선언하기

App 컴포넌트의 return 부에 export한 Context를 컴포넌트로 선언합시다.

    <DiaryDispatchContext.Provider value={data,onCreate,onRemove,onEdit}>
        // ... 하위 컴포넌트들 .. 
     </DiaryDispatchContext.Provider>

과연 이렇게 쉽게 끝날까요? ㅎㅎ 당연히 아니죠. (*data는 state를 담음)

질문 1.
DiaryDispatchContext가 공급하는 value의 상태관리 함수들을 data와 함께 나열식으로 전달해주면 안됩니다. 왜일까요?

먼저 DiaryStateContext.Providervalue{data, onCreate, onRemove, onEdit}처럼 함수와 data를 함께 묶은 '객체'를 전달하게 되면 data의 값이 변경될 때 이 '객체' 자체가 다시 생성됩니다. (그렇기 때문에 Provider를 분리하여 관리합니다.)

이에 따라 함수는 재생성되지 않지만 DiaryStateContext.Provider에게 전달되는 value가 재생성되기 때문에 리렌더가 발생하게 됩니다.
이러면 각각의 상태함수에 useCallback()을 적용한게 의미가 없어지게 됩니다.

그럼 어떻게 작성을 해야할까요?

상태관리 함수를 객체로 묶어서 value를 전달하기

최적화가 풀리지 않기 위해서, 값을 return하는 useMemo()로 한번 더 이 3개의 함수들을 묶어주면 됩니다.

  const memoizedDispatches = useMemo(()=>{
    return {onCreate,onRemove,onEdit};
  },[]);

memoizedDispatchesDiaryStateContext.Provider의 value로 assign 하여 해결할 수 있습니다.

질문 2.
왜 상태관리 함수들을 useMemo()로 한번 더 랩핑하여 value로 전달하나요?

useMemo로 묶는 이유는 객체를 재생성하지 않기 위함입니다.

DiaryDispatchContext.Provider에게 value로 전달하는 객체에 담기는 함수들이 useCallback으로 재생성되지 않도록 만들어졌다고 해도, data State가 변하는 순간 App 컴포넌트가 리렌더되어 DiaryDispatchContext.Provider에게 전달하는 객체 자체가 재생성됩니다.

(명심해야 할건 개발자 도구로 확인 시, 최상위 컴포넌트는 App입니다.)

따라서 객체 자체도 재생성하지 않게 하기 위해 useMemo를 사용한 것으로 볼 수 있습니다.

하위 컴포넌트 리팩토링

App 컴포넌트에서 마지막으로 해줘야 할 부분은, 각 하위 컴포넌트에 Props로 보내준 코드는 더이상 필요가 없으므로, 삭제해줘도 됩니다.

그리고 각 하위 컴포넌트에 해당하는 Provider에 맞게 import를 해줍니다.

import {DiaryDispatchContext} from "./App";

const DiaryEditor = () => {
    const {onCreate} = useContext(DiaryDispatchContext);
};

기존 코드에서는 DiaryEditor의 매개변수로 Props를 전달받았지만, 이젠 App 컴포넌트에 선언된 DiaryDispatchContext Provider로부터 값을 useContext()로 비구조화 할당을 받게 됩니다.

정리

이와 같이 상태값의 변화에 따른 리렌더링을 고려하며 Provider를 분리하는 동기에 대해서 알아보고, 그리고 최적화가 된 상태관리 함수들을 Provider의 value에 어떤 형식으로 전달해야되는지에 대해서 알아봤습니다.

0개의 댓글