useReducer
- 컴포넌트 내부에 새로운 State를 생성하는 React Hook이다.
- 모든 useState는 useReducer로 대체 가능하다.
- 상태 관리 코드를 컴포넌트 외부로 분리할 수 있다.
- UI를 렌더링하는 코드보다 상태를 관리하는 코드가 길어진다면 그것은 주객이 전도된 상황이다.
그럴 때 useReducer 함수를 사용한다.
Exam.jsx
import { useReducer } from "react";
// reducer : 변환기
// -> 상태를 실제로 변화시키는 변환기 역할
function reducer(state, action) {
// if (action.type === "INCREASE") {
// return state + action.data;
// } else if (action.type === "DECREASE") {
// return state - action.data;
// }
switch (action.type) {
case "INCREASE":
return state + action.data;
case "DECREASE":
return state - action.data;
default:
return state;
}
}
const Exam = () => {
// dispatch : 발송하다, 급송하다
// -> 상태 변화가 있어야 한다는 사실을 알리는, 발송하는 함수
const [state, dispatch] = useReducer(reducer, 0);
const onClickPlus = () => {
// 인수 : 상태가 어떻게 변화되길 원하는지
// -> 액션 객체
dispatch({
type: "INCREASE",
data: 1,
});
};
const onClickMinus = () => {
dispatch({
type: "DECREASE",
data: 1,
});
};
return (
<div>
<h1>{state}</h1>
<button onClick={onClickPlus}>+</button>
<button onClick={onClickMinus}>-</button>
</div>
);
};
export default Exam;
- reducer 안은 switch 문으로 하는 것이 일반적이다.
- dispatch 함수안에 있는 객체를 액션 객체라고 한다. reducer 함수에서 action 매개변수로 받는다.
Todo List 업그레이드 하기
App.jsx
import "./App.css";
import Header from "./components/Header";
import Editor from "./components/Editor";
import List from "./components/List";
import { useRef, useReducer } from "react";
const mockDate = [
{
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;
}
}
function App() {
const [todos, dispatch] = useReducer(reducer, mockDate);
const idRef = useRef(3);
const onCreate = (content) => {
dispatch({
type: "CREATE",
data: {
id: idRef.current++,
isDone: false,
content: content,
date: new Date().getTime(),
},
});
};
const onUpdate = (targetId) => {
dispatch({
type: "UPDATE",
targetId: targetId,
});
};
const onDelete = (targetId) => {
dispatch({
type: "DELETE",
targetId: targetId,
});
};
return (
<div className="App">
<Header />
<Editor onCreate={onCreate} />
<List todos={todos} onUpdate={onUpdate} onDelete={onDelete} />
</div>
);
}
export default App;
- useReducer로 이벤트 헨들러 안에서는 dispatch만 사용하여 코드를 깔끔하게 정리할 수 있다.
출처 : 한입 크기로 잘라먹는 리액트
'Language > React.js' 카테고리의 다른 글
[React] TodoList 프로젝트 : React Context (0) | 2024.10.21 |
---|---|
[React] TodoList 프로젝트 : 최적화 (Optimization), useMemo, useCallBack (0) | 2024.10.21 |
[React] TodoList 프로젝트 : 시작 (0) | 2024.10.18 |
[React] 라이프 사이클 (1) | 2024.10.17 |
[React] useRef와 Custom Hooks (0) | 2024.10.17 |