만약에 onRemove를 onDelte라고 이름을 바꾸고 싶다면 매우 번거로울 것이다.
props가 땅을 파고 드는것 같다고 해서 이 현상을 props drilling 이라고 한다!
여튼 이를 방지하기 위해서는 최상위 props를 하위 컴포넌트에서도 접근가능하게 하면 될것이다.
Provider 컴포넌트를 이용하면 props를 직통으로 공급해주어 props drilling이 사라진다.
해당 provider가 공급하는 데이터에 접근할 수 있는 컴포넌트들의 영역을 Context라고 한다.
const MyContext = React.createContext(defaultValue); // Context 생성
<MyContext.Provider value={전역으로 전달하고자하는 값}>
{/*이 context안에 위치할 자식 컴포넌트들*/}
</MyContext.Provider>
App.js에서 최상단으로 자식컴포넌트들을 감싸주고 data 값을 공급해준다.
data값이 있으니 DiaryList의 dairylist props는 지워주면 됨. ㅎㅎ
<DiaryStateContext.Provider value={data}>
<div className="App">
<DiaryEditor onCreate={ onCreate } />
<div>전체 일기 : {data.length}</div>
<div> 기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수:{badCount}</div>
<div>기분 좋은 일기 비율:{ goodRatio }%</div>
<DiaryList onDelete={onDelete} onEdit={onEdit}/>
</div>
</DiaryStateContext.Provider>
DairyList 에서는 data를 받아야 하니까,
const diaryList = useContext(DiaryStateContext);
props drilling을 일으켰던, onEdit,onRemove를 해결해보자..
value에다가 data를 넣은듯이 두개를 넣으면 안된다!
왜냐하면,, provider도 컴포넌트이므로 data값이 바뀔때마다 계속 리렌더링 되어서, 최적화 시켰던 코드가 무용지물이 되기 때문이다!
이를 해결하기 위해 context를 안에 더 넣어주면된다.
onCreate,onEdit,onRemove 함수들을 재생성되지 않게 메모제이션 해주면 된다.
const memoizedDispatches = useMemo(()=>{
return {onCreate,onDelete,onEdit}
},[])
✨완성✨
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider value={memoizedDispatches}>
<div className="App">
<DiaryEditor onCreate={ onCreate } />
<div>전체 일기 : {data.length}</div>
<div> 기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수:{badCount}</div>
<div>기분 좋은 일기 비율:{ goodRatio }%</div>
<DiaryList onDelete={onDelete} onEdit={onEdit}/>
</div>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>