Reducer와 Context
- Reducer를 사용하면 컴포넌트의 state 업데이트 로직을 통합할 수 있다.
- Context를 사용하면 다른 컴포넌트들에 정보를 전달할 수 있다.
reducer와 context를 결합하기
- state와 dispatch 함수를 props를 통해 전달하느 대신 context에 넣어서 사용할 수 있는데, 이점은 prop drilling 없이 TaskBoard 아래의 모든 컴포넌트 트리에서 tasks를 읽고 dispatch 함수를 실행 할 수 있다.
Reducer와 context 결합 방법
1. context를 생성한다.
2. state과 dispatch 함수를 context에 넣는다.
3. 트리 안에서 context를 사용한다.
Step1: Context 생성하기
- 트리를 통해 전달하려면, 두개의 별개의 context를 생성한다.
예)
- TasksContext는 현재 tasks 리스트를 제공한다.
- TasksDispatchContext는 컴포넌트에서 action을 dispatch 하는 함수를 제공한다.
import { createContext } from 'react';
export const TasksContext = createContext(null);
export const TasksDispatchContext = createContext(null);
Step2: State와 dispatch 함수를 context에 넣기
import { TasksContext, TasksDispatchContext } from './TasksContext.js';
export default function TaskApp() {
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
// ...
return (
<TasksContext.Provider value={tasks}>
<TasksDispatchContext.Provider value={dispatch}>
...
</TasksDispatchContext.Provider>
</TasksContext.Provider>
);
}
트리 안에서 context 사용하기
export default function TaskList() {
const tasks = useContext(TasksContext);
// ...
export default function AddTask() {
const [text, setText] = useState('');
const dispatch = useContext(TasksDispatchContext);
// ...
return (
// ...
<button onClick={() => {
setText('');
dispatch({
type: 'added',
id: nextId++,
text: text,
});
}}>Add</button>
// ...
- TaskBoard 컴포넌트는 자식 컴포넌트에, TaskList는 Task 컴포넌트데 이벤트 핸들러를 전달하지 않는다.
하나의 파일로 합치기
1. Reducer로 state를 관리한다.
2. 두 context를 모두 자식 컴포넌트에 제공한다.
3. children을 prop을 받기 때문에 JSX를 전달할 수 있다.
export function TasksProvider({ children }) {
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
return (
<TasksContext.Provider value={tasks}>
<TasksDispatchContext.Provider value={dispatch}>
{children}
</TasksDispatchContext.Provider>
</TasksContext.Provider>
);
}
import AddTask from './AddTask.js';
import TaskList from './TaskList.js';
import { TasksProvider } from './TasksContext.js';
export default function TaskApp() {
return (
<TasksProvider>
<h1>Day off in Kyoto</h1>
<AddTask />
<TaskList />
</TasksProvider>
);
}
- TasksContext.js에서 context를 사용하기 위한 use 함수들도 내보낼 수 있습니다.
export function useTasks() {
return useContext(TasksContext);
}
export function useTasksDispatch() {
return useContext(TasksDispatchContext);
}
const tasks = useTasks();
const dispatch = useTasksDispatch();
-> 컴포넌트들이 데이터를 어디서 가져오는지가 아닌 무엇을 보여줄 것인지에 집중할 수 있도록 깨끗하게 정리할 수 있다.
참고
https://react-ko.dev/learn/scaling-up-with-reducer-and-context
'개발 공부' 카테고리의 다른 글
개발 버전 관리 (1) | 2023.10.17 |
---|---|
[React+TypeScript] ShortPolling, LongPolling, SSE, WebSocket 차이점 (0) | 2023.09.24 |
[리액트 공식 문서] context로 데이터 깊숙이 전달하기 (0) | 2023.09.06 |
[리액트 공식 문서] state 로직을 reducer로 추출하기 (0) | 2023.09.06 |
[리액트 공식 문서] Quick start~ Thinking in React (0) | 2023.08.18 |