리액트의 컴포넌트 트리에 전형적으로 데이터를 공급
Props Drilling 문제 해결
: 부모에서 자식으로만 데이터를 전달하는 단방향 데이트 흐름을 가진 리액트 특성상 발생하게 문제를 해결하기 위해 나온 Context Provider
라는 공급자 역할을 하는 자식 컴포넌트에게 자신이 가지고 있는 모든 데이터를 준다직통으로 데이터를 줄 수가 있다
(Props Drilling 제거)코드 가독성이 좋아진다.
src/App.js
import React, { useCallback, useEffect, useMemo, useRef, useReducer } from "react";
export const DiaryStateContext = React.createContext();
function App() {
return (
<DiaryStateContext.Provider value={data}>
<div className="App">
<DiaryEditor />
<div>전체 일기 : {data.length}</div>
<div>기분 좋은 일기 개수 : {goodCount}</div>
<div>기분 나쁜 일기 개수 : {badCount}</div>
<div>기분 좋은 일기 비율 : {goodRatio}</div>
<DiaryList />
</div>
</DiaryStateContext.Provider>
);
};
data state
다. 그래서 value prop
에 data state를 보내주기만 하면 우리가 전달하고 싶은 App 컴포넌트의 data state를 잘 받았다는 것을 확인할 수 있다. (모든 데이터를 공급하는 Provider)src/DiaryList.js
import { useContext } from 'react';
import { DiaryStateContext } from './App';
import DiaryItem from './DiaryItem';
const DiaryList = ({ onEdit, onRemove }) => {
const diaryList = useContext(DiaryStateContext);
return (
<div className="DiaryList">
<h2>일기 리스트</h2>
<h4>{diaryList.length}개의 일기가 있습니다.</h4>
<div>
{diaryList.map((it) => (
<DiaryItem key={it.id} {...it} onEdit={onEdit} onRemove={onRemove} />
))}
</div>
</div>
);
};
DiaryList.defaultProps = { diaryList: [] };
export default DiaryList;
src/App.js
export const DiaryDispatchContext = React.createContext();
function App () {
const memoizedDispatches = useMemo(()=>{
return {onCreate, onRemove, onEdit}
}, []);
return (
<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>
);
};
context를 중첩해서 만들기 (이중문맥)
: DiaryStateContext는 모든 데이터를 공급하기 위해서만 최상위에 두고, onCreate, onRemove, onEdit같은 state 변화시키는 함수는 dispatch 함수에 내보내고 있기 때문에 새로운 context를 만들어서 하위에 둔다. (데이터 공급 context - 상태 변화 context
)memoizedDispatches
: onCreate, onRemove, onEdit는 재생성되지 않는 함수들이므로 절대 리렌더링이 되지 않게 묶어준다
(useMemo를 활용해서 재생성되지 않게 객체로 묶어주고 빈 배열로 deps 전달) 그런 다음 DiaryDispatchContext의 value로 전달해준다.src/DiaryEditor.js
import React, { useState, useRef, useContext } from "react";
import { DiaryDispatchContext } from "./App";
const DiaryEditor = () => {
const {onCreate} = useContext(DiaryDispatchContext);
};
src/DiaryList.js
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>
);
};
src/DiaryItem.js
import React, { useContext, useRef, useState } from "react";
import { DiaryDispatchContext } from "./App";
const DiaryItem = ({ id, author, content, emotion, created_date
}) => {
const { onRemove, onEdit } = useContext(DiaryDispatchContext);
};
💬 기본 편 드디어 끝!인데 성능 최적화부터 어려운 거 같다.
다음 실전 편(감성일기장) 만들기 전에 복습하기 위해 한번 더 정주행할 예정인데 이해가 안 가는 부분..
💬 난 저 공급자라는 단어를 떠올리면 생각나는 게 있다. "그건 너무 공급자 마인드예요" 그땐 사실 속으론 공급자 솔루션이니까 당연한 거 아닌가? 싶었는데 사용자를 조금 더 넓게 보면 무슨 말인지는 알 것 같다. 공부하다가 문득 생각남..ㅋㅋ