이어서...
두 번째 upgrade를 진행해볼 것이다
현재상태이다 보시다시피 onRemove()와 onEdit()은 DiaryList에서 쓰이지 않지만 DiaryItem에서 필요함으로
부모라는 이유만으로 Props drilling이 일어난다 그럼 유지보수에 힘들어지므로 이 부분을 업그레이드해볼 것이다
모든 데이터를 가지고 있는 컴포넌트가 Provider라는 공급자 역할를 하는 자식 컴포넌트에게 자신이 가지고있는
모든 데이터를 다 준다 그럼 이 Provider는 특별하게 자신의 자손에 해당하는 모든 컴포넌트들에게
직통으로 데이터를 보내줄 수 있다 즉 Props drilling이 없어지게 하는 것이다
이렇게 Provider컴포넌트의 자식 컴포넌트로 배치되어 Provider에서 제공하는 모든 데이터에 접근할 수 있는
이런 컴포넌트의 영역을 Context라고 한다
리액트의 context객체는 이런 식으로 생성한다
const MyContext = React.createContext(defaultValue);
그 후 이렇게 컴포넌트로 사용하면 된다
<MyContext.Provider value={전역으로 전달하고자하는 값}>
{/*이 context안에 위치할 자식 컴포넌트 들*/}
</Mycontext.Provider>
App.js에 넣어보자
export const DiaryStateContext = React.createContext();
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} onDelete={onDelete} onEdit={onEdit}/>
</div>
</DiaryStateContext.Provider>
);
최상위 태그를 DiaryStateContext.Provider로 바꿔준다 다음 value값으로 data를 보내주면 된다
그럼 자식 컴포넌트들은 더 이상 data와 관련된 값들을 props로 받지 않아도 되는 것이다.
<DiaryList diaryList={data} onDelete={onDelete} onEdit={onEdit}/>
보면 DiaryList는 data를 prop으로 보내는데 이것을 더 이상 prop으로 보내지 않아도 된다는 것이다
<DiaryList onDelete={onDelete} onEdit={onEdit}/>
이렇게 prop을 지워주고
const DiaryList = ({onDelete,onEdit})=>{
const diaryList = useContext(DiaryStateContext);
...
)
}
이런 식으로 useContext를 data의 값을 공급받는다
그럼 같은 방식으로 onCreate, onDelete, onEdit 도 바꿔보자
export const DiaryDispatchContext = React.createContext();
function App() {
...
const memoizedDispatches = useMemo(()=>{
return{onCreate,onDelete,onEdit}
return (
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider value={memoizedDispatches} >
...
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
);
},[])
context하나를 더 만들어주고
onCreate, onDelete, onEdit를 리턴하는 useMemo로 감싼 memoizedDispatches 객체를 만들어
DiaryDispatchContext.Provider value값으로 보내준다
DiaryEditor
import React, { useContext, useEffect,useRef,useState } from "react";
import { DiaryDispatchContext } from "./App";
const DiaryEditor=()=>{
const {onCreate} = useContext(DiaryDispatchContext)
...
}
export default React.memo(DiaryEditor);
prop을 지워주고 DiaryDispatchContext에서 useContext를 통해 onCreate를 받아준다
DiaryList
import { useContext } from "react";
import { DiaryStateContext } from "./App";
import DiaryItem from "./DiaryItem";
const DiaryList = ()=>{
const diaryList = useContext(DiaryStateContext);
return(
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length}개의 일기가 있습니다</h4>
<div>
{diaryList.map((it)=>(
<DiaryItem key={it.id} {...it}/>
))}
</div>
</div>
)
}
DiaryList.defaultProps={
diaryList: [],
}
export default DiaryList;
DiaryItem
import React,{ useContext, useRef, useState } from "react";
import { DiaryDispatchContext } from "./App";
const DiaryItem=({
author,
content,
emotion,
created_date,
id,
})=>{
const{onDelete,onEdit}=useContext(DiaryDispatchContext);
...
}
export default React.memo(DiaryItem);
나머지도 다 같은 방식으로 고쳐보았다
이렇게 해서 리액트로 간단한 일기장 만들기가 완성되었다!
많은 리액트의 기능들을 배웠보았다!
끝.
'개발🐕 > React' 카테고리의 다른 글
[React] 리액트 프로젝트 배포 준비 & 프로젝트 빌드 (0) | 2023.01.13 |
---|---|
[React] 리액트 페이지 라우팅 SPA와 CSR (2) | 2023.01.09 |
[React Project: 간단한 일기장(9)] 로직 분리하기 -useReducer (0) | 2023.01.06 |
[React Project: 간단한 일기장(8)] 최적화3 - useCallback (0) | 2023.01.05 |
[React Project: 간단한 일기장(7)] 최적화2 - React.memo (0) | 2023.01.05 |