컴포넌트가 복잡해지면 컴포넌트의 state가 업데이트되는 다양한 경우를 한눈에 파악하기 어려울 수 있습니다. 복잡성을 줄이기 위해 state 로직을 컴포넌트 외부의 reducer라는 단일 함수로 통합 관리할 수 있습니다.
reducer는 state를 다루는 다른 방법입니다. 다음과 같은 세 가지 단계에 걸쳐 useState에서 useReducer로 바꿀 수 있습니다.
- state를 설정하는 것에서 action을 dispatch 함수로 전달하는 것으로 바꾸기.
- reducer 함수 작성하기.
- 컴포넌트에서 reducer 사용하기.
function handleAddTodo(text) {
dispatch({
type: 'added',
id: nextId++,
text: text,
});
}
function handleChangeTask(task) {
dispatch({
type: 'changed',
task: task
});
}
function handleDeleteTask(taskId) {
dispatch({
type: 'deleted',
id: taskId
});
}
reducer 함수에는 두 개의 매개변수를 가지는데, 하나는 현재 state이고 하는 action객체입니다. 이 함수가 다음 state를 반환(return)하며 컴포넌트 외부에서 선언합니다.
function todosReducer(todos, action){
switch(action.type){
case 'added' : {
return [...todos, {id:action.id, text:action.text}]
}
case 'changed' : {
return todos.map(todo=>
if(todo.id===action.todo.id){
return action.todo;
}else {
return todo;
}
});
}
case 'deleted' : {
return tasks.filter((todo) => todo.id !== action.id);
}
}
}
마지막으로 컴포넌트에 reducer를 연결해야 합니다.
import {useReducer} from 'react';
const [todos, dispatch]=useReducer(todosReducer, initialTodos);
useReducer 장점
많은 이벤트 핸들러가 있다면 로직이 어떻게 동작하는지와 이벤트 핸들러를 통해 무엇이 일어났는지 깔끔하게 분리할 수 있습니다. 디버깅할 때도 useState는 어디서 잘못 설정되었는지부터 확인해야 하지만 어떤 action으로 인해 버그를 발생했는지를 확인하면 됩니다. reducer는 컴포넌트에 의존하지 않는 순수한 함수이기 때문에 분리해서 테스트할 수 있습니다.
useReducer 주의점
reducer는 반드시 순수해야 하고 또한 객체와 배열을 변이 없이 업데이트해야 합니다. 각 action은 여러 업데이트가 변경되더라도, 하나의 사용자 상호작용으로 설명해야 합니다.
** reducer는 reduce() 연산에서 가져온 이름입니다. reduce()은 배열의 여러 값을 하나의 값으로 누적하는 연산을 수행합니다. reduce로 전달하는 함수는 reducer로 알려져 있고, 지금까지의 결과와 현재 아이템을 가지고, 다음 결과를 반환합니다. 비슷한 아이디어로 React의 reducer는 지금까지의 state와 action을 인자로 받고 다음 state를 반환합니다.
** React18 공식 문서 보고 정리한 내용입니다.
https://ko-react-exy5xcwjj-fbopensource.vercel.app/learn/extracting-state-logic-into-a-reducer
state 로직을 reducer로 작성하기 – React
The library for web and native user interfaces
ko.react.dev
'Dev > React.js' 카테고리의 다른 글
[React18] 10. ref (1) | 2023.10.03 |
---|---|
[React18] 9. context (0) | 2023.10.02 |
[React18] 7. state 관리하기 (0) | 2023.09.30 |
[React18] 6. state 업데이트 (0) | 2023.09.29 |
[React18] 5. useState와 React의 렌더링 (0) | 2023.09.28 |
댓글