728x90
리액트 공식문서 학습기록
https://react.dev/learn
Scaling Up with Reducer and Context
리듀서와 컨텍스트 결합
컴포넌트가 많아질수록 리듀서의 상태 및 함수 전달이 힘듬. 따라서 props 대신 tasks와 dispatch 함수를 컨텍스트에 넣어 사용.
1단계 - 컨텍스트 만들기
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
나중에 다른 파일에서 가져다 쓰게 별도의 파일에서 export함.
import { createContext } from 'react';
export const TasksContext = createContext(null);
export const TasksDispatchContext = createContext(null);
2단계 - 상태 및 디스패치를 컨텍스트에 넣기
요런 너낌으로 넣어서 전체 트리에 제공
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>
);
}
3단계 - 트리의 아무곳에서나 컨텍스트 사용
tasks나 이벤트 핸들러를 트리 아래로 전달할 필요없음.
export default function TaskList() {
const tasks = useContext(TasksContext);
export default function AddTask() {
const [text, setText] = useState('');
const dispatch = useContext(TasksDispatchContext);
tasks랑 dispatch를 통합
import { createContext } from 'react';
export const TasksContext = createContext(null);
export const TasksDispatchContext = createContext(null);
export function TasksProvider({ children }) {
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
return (
<TasksContext.Provider value={tasks}>
<TasksDispatchContext.Provider value={dispatch}>
{children}
</TasksDispatchContext.Provider>
</TasksContext.Provider>
);
}
아래처럼 컨텍스트를 사용하는 함수를 정의해서 쓸 수도 있음
export function useTasks() {
return useContext(TasksContext);
}
export function useTasksDispatch() {
return useContext(TasksDispatchContext);
}
const tasks = useTasks();
const dispatch = useTasksDispatch();
한 코드로 정리
import { createContext, useContext, useReducer } from 'react';
const TasksContext = createContext(null);
const TasksDispatchContext = createContext(null);
export function TasksProvider({ children }) {
const [tasks, dispatch] = useReducer(
tasksReducer,
initialTasks
);
return (
<TasksContext.Provider value={tasks}>
<TasksDispatchContext.Provider value={dispatch}>
{children}
</TasksDispatchContext.Provider>
</TasksContext.Provider>
);
}
export function useTasks() {
return useContext(TasksContext);
}
export function useTasksDispatch() {
return useContext(TasksDispatchContext);
}
function tasksReducer(tasks, action) {
switch (action.type) {
case 'added': {
return [...tasks, {
id: action.id,
text: action.text,
done: false
}];
}
case 'changed': {
return tasks.map(t => {
if (t.id === action.task.id) {
return action.task;
} else {
return t;
}
});
}
case 'deleted': {
return tasks.filter(t => t.id !== action.id);
}
default: {
throw Error('Unknown action: ' + action.type);
}
}
}
const initialTasks = [
{ id: 0, text: 'Philosopher’s Path', done: true },
{ id: 1, text: 'Visit the temple', done: false },
{ id: 2, text: 'Drink matcha', done: false }
];
'공부공부 > React' 카테고리의 다른 글
[react 공식문서] 24 Manipulating the DOM with Refs (0) | 2024.02.14 |
---|---|
[react 공식문서] 23 Referencing Values with Refs (0) | 2024.02.14 |
[react 공식문서] 21 Passing Data Deeply with Context (0) | 2024.02.14 |
[react 공식문서] 20 Extracting State Logic into a Reducer (0) | 2024.02.14 |
[react 공식문서] 19 Preserving and Resetting State (0) | 2024.02.14 |