export const DiaryStateContext = React.createContext();
DiaryStateContext 내보내주어야 다른 곳에서 쓸 수 있다.
export default는 파일 하나의 하나만 쓸 수 있다.
그래서 export만 써주면 여러 개를 쓸 수 있다.
return (
<DiaryStateContext.Provider value={data}>
<div className="App">
<DiaryEditor onCreate={onCreate} />
<div>전체 일기 : {data.length}</div>
<div>기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수 : {badCount}</div>
<div>기분 좋은 일기 비율 : {goodRatio}</div>
<DiaryList diaryList={data} onEdit={onEdit} onRemove={onRemove}/>
</div>
</DiaryStateContext.Provider>
);
Provider 컴포넌트로 랩핑을 해준다.
value={data} 이런식으로 값(데이터)을 내려주어야한다.
DiaryList.js
import { useContext } from 'react';
import { DiaryStateContext } from './App';
const diaryList = useContext(DiaryStateContext);
useContext 으를 활용해 App.js 에서 내보냈던 DiaryStateContext 값을 가져와서, hooks 저장됨
그래서 더이상 App.js에서 diaryList를 props로 전달해줄 필요가 없다.
App.js
<DiaryList diaryList={data} onEdit={onEdit} onRemove={onRemove}/>
diaryList={data} 를 삭제해준다.
<DiaryList onEdit={onEdit} onRemove={onRemove}/>
onEdit,onRemove context.Provider 만들어주자.
이때 주의 할 점은 기존처럼 <DiaryStateContext.Provider value={data}> onEdit,onRemove 값을 추가하면안된다.
Provider도 컴포넌트이기 때문에 data가 바뀌면 전부 리렌더링이 되어지기때문에 기존에 만든 최적화가 의미가 없어진다.
이럴경우 context.Provider를 중첩으로 사용하자
data값을 각각 따로 맞는다.
export const DiaryDispatchContext = React.createContext();
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider>
<div className="App">
<DiaryEditor onCreate={onCreate} />
<div>전체 일기 : {data.length}</div>
<div>기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수 : {badCount}</div>
<div>기분 좋은 일기 비율 : {goodRatio}</div>
<DiaryList onEdit={onEdit} onRemove={onRemove}/>
</div>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
이런식으로 이중으로 감싸져있다.
onRemove, onEdit, onCreate값을 하나로 묶어서 전달하자.
const memoizedDispatches = useMemo(() => {
return {onCreate, onRemove, onEdit}
},[]);
useMemo 를 사용해 재생성되지 않게 해준다.
만약 밑에 있는 것처럼, 값만 전달할경우 app컴포넌트가 재생성될때 dispatch 값도 재생성된다.
const dispatch = {
onCreate, onRemove, 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 onEdit={onEdit} onRemove={onRemove}/>
</div>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
기존에 있던 onCreate, onEdit, onRemove props를 삭제해준다.
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider value={memoizedDispatches}>
<div className="App">
<DiaryEditor />
<div>전체 일기 : {data.length}</div>
<div>기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수 : {badCount}</div>
<div>기분 좋은 일기 비율 : {goodRatio}</div>
<DiaryList/>
</div>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
DiaryEditor.js
import React,{ useContext, useEffect, useState, useRef } from 'react';
import { DiaryDispatchContext } from './App.js';
const { onCreate } = useContext(DiaryStateContext);
객체로 전달됨으로 비구조화 할당으로 전달 받아야한다.
DiaryItem.js
import React,{ useContext, useEffect, useState, useRef } from 'react';
import { DiaryDispatchContext } from './App.js';
const { onRemove, onEdit } = useContext(DiaryDispatchContext);
기존에 prop으로 전달받았던 onRemove,onEdit 값은 삭제 해주어야한다.