
Context란?
컴포넌트간의 데이터를 전달하는 또 다른 방법
기존의 Props가 가지고있는 단점을 보완
Props의 단점
props를 계층구조상에서 B까지 전달하려면 A한테 주고 A한테서 받는 형태로 진행했어야했음
서비스의 규모가 커져서 많은 컴포넌트들을 거쳐야하는 상황에서 굉장히 좋지 않음
React Context로 해결!
React Context
context : 데이터 보관소(객체)
context에 보관해놓고 필요한 곳에 데이터를 공급하는게 가능함
//보통 컴포넌트 외부에서 생성
const TodoContext = createContext();
import "./App.css";
import {
useRef,
useState,
useReducer,
useCallback,
createContext,
} from "react";
import Header from "./components/Header";
import Editor from "./components/Editor";
import List from "./components/List";
const mockData = [
{
id: 0,
isDone: false,
content: "React 공부하기",
date: new Date().getTime(),
},
{
id: 1,
isDone: false,
content: "빨래하기",
date: new Date().getTime(),
},
{
id: 2,
isDone: false,
content: "노래 연습하기",
date: new Date().getTime(),
},
];
function reducer(state, action) {
switch (action.type) {
case "CREATE":
return [action.data, ...state];
case "UPDATE":
return state.map((item) =>
item.id === action.targetId
? { ...item, isDone: !item.isDone }
: item
);
case "DELETE":
return state.filter((item) => item.id !== action.targetId);
default:
return state;
}
}
export const TodoContext = createContext();
function App() {
const [todos, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(3);
const onCreate = useCallback((content) => {
dispatch({
type: "CREATE",
data: {
id: idRef.current++,
isDone: false,
content: content,
date: new Date().getTime(),
},
});
}, []);
const onUpdate = useCallback((targetId) => {
dispatch({
type: "UPDATE",
targetId: targetId,
});
}, []);
const onDelete = useCallback((targetId) => {
dispatch({
type: "DELETE",
targetId: targetId,
});
}, []);
return (
<div className="App">
<Header />
<TodoContext.Provider
value={{
todos,
onCreate,
onUpdate,
onDelete,
}}
>
<Editor />
<List />
</TodoContext.Provider>
</div>
);
}
export default App;
context 분리하기
최적화를 위해서 context를 적용했을 때 분리해서 공급해주면 문제를 해결할 수 있음
todos가 업데이트가 된다하더라도 다른 컴포넌트들은 리렌더링 되지 않음
import "./App.css";
import {
useRef,
useState,
useReducer,
useCallback,
createContext,
useMemo,
} from "react";
import Header from "./components/Header";
import Editor from "./components/Editor";
import List from "./components/List";
const mockData = [
{
id: 0,
isDone: false,
content: "React 공부하기",
date: new Date().getTime(),
},
{
id: 1,
isDone: false,
content: "빨래하기",
date: new Date().getTime(),
},
{
id: 2,
isDone: false,
content: "노래 연습하기",
date: new Date().getTime(),
},
];
function reducer(state, action) {
switch (action.type) {
case "CREATE":
return [action.data, ...state];
case "UPDATE":
return state.map((item) =>
item.id === action.targetId
? { ...item, isDone: !item.isDone }
: item
);
case "DELETE":
return state.filter((item) => item.id !== action.targetId);
default:
return state;
}
}
export const TodoStateContext = createContext();
export const TodoDispatchContext = createContext();
function App() {
const [todos, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(3);
const onCreate = useCallback((content) => {
dispatch({
type: "CREATE",
data: {
id: idRef.current++,
isDone: false,
content: content,
date: new Date().getTime(),
},
});
}, []);
const onUpdate = useCallback((targetId) => {
dispatch({
type: "UPDATE",
targetId: targetId,
});
}, []);
const onDelete = useCallback((targetId) => {
dispatch({
type: "DELETE",
targetId: targetId,
});
}, []);
const memoizedDispatch = useMemo(() => {
return { onCreate, onUpdate, onDelete };
}, []);
return (
<div className="App">
<Header />
<TodoStateContext.Provider value={todos}>
<TodoDispatchContext.Provider value={memoizedDispatch}>
<Editor />
<List />
</TodoDispatchContext.Provider>
</TodoStateContext.Provider>
</div>
);
}
export default App;
'Frontend > React.js' 카테고리의 다른 글
[TypeScrip.js] alt 속성에 대하여 (0) | 2024.06.17 |
---|---|
[React.js] 페이지 라우팅 (0) | 2024.06.12 |
[React.js] 최적화 (1) | 2024.06.12 |
[React.js] 라이프 사이클 (0) | 2024.06.11 |
[React.js] 리액트 입문 (0) | 2024.06.11 |