
useReducer
- useReducer()을 는 상태와 그 상태를 업데이트하는 함수를 반환하는 React 훅입니다. 이 훅은 상태를 업데이트하는 로직을 함수 형태로 분리해 관리한다.
- useReducer은 기본적으로 Redux에서 사용하는 패턴과 유사하게 동작하며, 상태 변경 로직을 컴포넌트 외부로 분리할 수 있어 상태 관리가 복잡해질 때 매우 유용하다.
const [state, dispatch] = useReducer(reducer, initialState);
- reducer
- 현재 상태와 액션을 기반으로 새로운 상태를 반환하는 함수
- initialState
- 초기 상태 값
- state
- 현재 상태를 나타낸다.
- dispatch
- 상태를 변경하기 위한 액션을 발생시키는 함수
useReducer의 역할
- 복잡한 상태 관리
- useState를 사용하면 여러 상태 변수를 개별적으로 관리해야 하는 경우가 많은데, useReducer을 사용하면 상태와 그 변화를 하나의 함수에서 관리할 수 있어 복잡한 상태 로직을 쉽게 다룰 수 있다.
- 코드 가독성 향상
- 상태 변화를 관리하는 로직을 reducer 함수로 분리하기 때문에 코드가 더 깔끔하고 가독성이 높아진다.
- 유지보수성 개선
- 상태 변경 로직이 한 곳에 모이므로, 유지보수와 테스트가 용이하다.
useState ⇒ useReducer
useState
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default Counter;
useReducer
import React, { useReducer } from 'react';
// reducer 함수 정의
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 initialState = { count: 0 };
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
}
export default Counter;
- reducer 함수는 현재 상태와 액션을 인자로 받아, 새로운 상태를 반환한다.
- dispatch 함수를 사용해 액션을 발생시키고, 이를 통해 상태를 변경한다.
useReducer 사용
- 복잡한 상태 로직이 필요한 경우
- 상태 업데이트 로직이 여러 가지 경우를 처리해야 할 때 useState가 더 적합하다.
- 여러 상태 변수나 다양한 액션 타입이 필요한 경우
- 상태 관리의 일관성
- 상태 변경 로직을 하나의 reducer 함수에 통합하면, 코드의 일관성을 유지하고 버그를 줄일 수 있다.
useReducer 객체 관리
import React, { useReducer } from 'react';
// reducer 함수
function reducer(state, action) {
switch (action.type) {
case 'setName':
return { ...state, name: action.payload };
case 'setAge':
return { ...state, age: action.payload };
case 'toggleIsStudent':
return { ...state, isStudent: !state.isStudent };
default:
throw new Error('Unknown action');
}
}
function UserProfile() {
const initialState = { name: '', age: 0, isStudent: false };
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Name: {state.name}</p>
<p>Age: {state.age}</p>
<p>Is Student: {state.isStudent ? 'Yes' : 'No'}</p>
<input
type="text"
placeholder="Set Name"
onChange={(e) => dispatch({ type: 'setName', payload: e.target.value })}
/>
<input
type="number"
placeholder="Set Age"
onChange={(e) => dispatch({ type: 'setAge', payload: parseInt(e.target.value) })}
/>
<button onClick={() => dispatch({ type: 'toggleIsStudent' })}>
Toggle Is Student
</button>
</div>
);
}
export default UserProfile;
- reducer를 통해 객체 안의 요소를 상태 관리할 수 있다.
결론
- useReducer은 useState보다 더 복잡한 상태 관리가 필요할 때 유용한 도구이다.
- 상태 업데이트 로직이 복잡해지거나 다양한 경우를 처리해야 한다면, useReducer로 전환하여 관리할 수 있다.
'FE' 카테고리의 다른 글
전역 상태관리 도구들 비교와 분석 정리 3.Zustand (0) | 2024.11.12 |
---|---|
전역 상태관리 도구들 비교와 분석 정리 2. Recoil (0) | 2024.11.09 |
전역 상태관리 도구들 비교와 분석 정리 1. Redux (0) | 2024.11.08 |
[FE] 기존 리액트 프로젝트를 PWA로 만드는 방법 (0) | 2024.08.17 |