useReducer
- 상태 관리 hook중 하나(useState처럼)
- 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리 가능 → 상태 업데이트 로직을 컴포넌트 바깥에 작성 가능, 심지어 다른 파일에 작성 후 불러와서 사용 가능
reducer: 현재 상태와 액션 객체를 파라미터로 받아와서 새로운 상태를 반환해주는 함수
function reducer(state, action) {
// 새로운 상태를 만드는 로직
// const nextState = ...
return nextState;
}
- 반환하는 상태는 곧 컴포넌트가 지닐 새로운 상태가 됨
- action은 업데이트를 위한 정보를 지니고 있음(객체의 형태는 자유) → type 값을 지닌 객체 형태로 사용
//카운터에 1을 더하는 액션
{
type: 'INCREMENT'
}
//카운터에 1을 빼는 액션
{
type: 'DECREMENT'
}
//input 값을 바꾸는 액션
{
type: 'CHANGE_INPUT',
key: 'email',
value: 'tester@react.com'
}
//새 할 일을 등록하는 액션
{
type: 'ADD_TODO',
todo: {
id: 1,
text: 'useReducer 배우기',
done: false,
}
}
useReducer 사용법
const [state, dispatch] = useReducer(reducer, initialState);
- state: 컴포넌트에서 사용할 수 있는 상태를 가리킴
- dispatch: 액션을 발생시키는 함수 → dispatch({type: ‘INCREMENT’})
- 첫 번째 파라미터: reducer 함수
- 두 번째 파라미터: 초기 상태
import React, { useReducer } from "react";
function reducer(state, action) {
switch (action.type) {
case "INCREMENT":
return state + 1;
case "DECREMENT":
return state - 1;
default:
return state;
}
}
function Counter() {
const [number, dispatch] = useReducer(reducer, 0);
const onIncrease = () => {
dispatch({ type: "INCREMENT" });
};
const onDecrease = () => {
dispatch({ type: "DECREMENT" });
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
function reducer(state, action) {
switch (action.type) {
case "CHANGE_INPUT":
return {
...state,
inputs: {
...state.inputs,
[action.name]: action.value,
},
};
default:
return state;
}
}
- reducer함수에서 새로운 상태 만들 때, 불변성 지켜주어야 함 → spread 연산자 사용
useReducer vs useState
→ 상황에 따라 다름
ex)
- 컴포넌트에서 관리하는 값이 하나이고, 그 값이 단순한 숫자 혹은 문자열, boolean값 → useState 로 관리하는 것이 편리
- 컴포넌트에서 관리하는 값이 여러 개가 되어서 상태의 구조가 복잡 → useReducer로 관리
'프론트엔드 > React' 카테고리의 다른 글
Context API (0) | 2022.11.24 |
---|---|
커스텀 Hooks 만들기 (0) | 2022.11.24 |
useCallback, React.memo (0) | 2022.11.24 |
useEffect와 useMemo (0) | 2022.11.23 |
컴포넌트 렌더링 (0) | 2022.11.23 |