useReducer는 state를 관리하는 또다른 훅이다.
하나의 state를 관리하는 useState와는 다르게 useReducer는 좀 더 복잡한 상태의 state를 관리할 수 있다.
useReducer 사용법은 아래와 같다.
const [state, dispatch] = useReducer(reducer, initialState);
공식 문서의 카운터 예시를 통해 더 자세히 알아보자.
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
</>
);
}
// 출처: https://reactjs.org/docs/hooks-reference.html#usereducer
reducer는 (currentState, action) 를 받아 newState를 리턴하는 함수이다.
이 action은 보통 { type: "type_name", payload: { value: "value" } } 이런식이라고 이해하면 된다.
reducer은 action의 타입에 따라 새로운 state를 리턴한다.
위 예제의 경우 type이 increment인 경우 count를 +1 하고 decrement인 경우 count를 -1 해서 새로운 state를 리턴하는 것을 볼 수 있다.
카운터 예제보다 조금 더 복잡한 예제를 살펴보기 위해 Todo List를 구현해보자.
Todo list를 위해 ADD, TOGGLE, DELETE 세가지 액션을 사용할 것이다.
우선 useReducer로 state와 dispatch를 정의한다.
const [state, dispatch] = useReducer(reducer, { todos: [] })
reducer 함수는 아래와 같을 것이다.
function reducer(state, action) {
switch (action.type) {
case ACTIONS.ADD:
// do something to add
return newState
case ACTIONS.TOGGLE:
// do something to toggle
return newState
case ACTIONS.DELETE:
// do something to delete
return newState
default:
return state
}
}
그런 다음 Todo 컴포넌트에 dispatch를 넘겨준다.
function App() {
...
return (
<div>
...
{state.todos.map(todo => <Todo key={todo.id} todo={todo} dispatch={dispatch} />}}
</div>
)
}
function Todo({ todo, dispatch }) {
return (
<div>
<button onClick={() => dispatch({ type: ACTIONS.TOGGLE, payload: { id: todo.id }})}>
toggle
</button>
<span>{todo.name}</span>
<button onClick={() => dispatch({ type: ACTIONS.DELETE, payload: { id: todo.id }})}>
delete
</button>
</div>
)
}
하위 컴포넌트인 Todo 컴포넌트에 dispatch를 넘겨주면 handleToggle, handleDelete 등을 따로 넘겨줄 필요 없이 하나로 넘겨줄 수 있어서 편하다.
또한 payload를 통해 원하는 value를 reducer로 보낼 수 있는 것도 장점이다.
이 글에서는 간단한 두 예제를 이용해 useReducer 사용법을 알아봤다.
Todo list 전체 코드는 여기에서 확인할 수 있다.
+ useReducer로 todo list를 구현하는 아이디어와 global non changing variable인 ACTIONS를 사용하는 방법은 [2]에서 참고했다.
Reference
[1] Hooks API Reference - React [Doc]
[2] Learn useReducer in 20 Minutes [Youtube] by Web Dev Simplfied
'개발 > 프론트엔드 (JS & React)' 카테고리의 다른 글
[React Hooks] Custom Hook examples 커스텀 훅 예제 (0) | 2022.09.27 |
---|---|
[React Hooks] useMemo & useCallback (0) | 2022.09.26 |
[React Hooks] Context API와 컴포넌트 합성(Component Composition) (0) | 2022.09.25 |
[React & Storybook] 2 - 스토리 작성 방법 (1) | 2022.09.23 |
[React & Storybook] 1 - 리액트에서 스토리북 사용하기 (0) | 2022.09.22 |