useReducer란?
useState처럼 상태를 관리하고 업데이트할 수 있는 리액트 내장 훅입니다.
useState와 useReducer 비교
문법이 비슷하지만 dispatch와 reducer 함수가 달라 보입니다.
//useState
const [ state, setState ] = useState(initialState);
//useReducer
const [ state, dispatch ] = useReducer(reducer,initialState);
useReducer의 구성요소는 다음과 같습니다.
- state : 상태의 이름
- dispatch : reducer함수를 실행시키고 상태를 업데이트 할 때 필요한 정보(기능, 재료)를 전달하는 함수
- reducer : dispatch로 전달된 데이터를 기반으로 상태를 업데이트하는 함수
- initialState : 상태의 초기값
useState는 컴포넌트 내에서 상태를 관리하지만, useReducer를 사용하면 해당 컴포넌트에서 상태 관리 로직을 분리할 수 있어서 가독성이나 유지보수성을 향상시킬 수 있습니다. 이때 필요한 함수가 dispatch와 reducer입니다. dispatch는 상태를 변경하는데 필요한 정보들을 reducer함수에 전달하고, reducer함수는 전달받은 정보들로 상태를 알맞게 변경시킵니다.
예시 코드
count라는 상태를 관리하고, count를 변화시키는 increase, decrease 함수를 만들어보겠습니다.
- increase 함수 : 기존 count에서 2만큼 증가시킵니다.
- decrease 함수 : 기존 count 값에서 1만큼 감소시킵니다.
1. App 컴포넌트
count 값을 보여줄 컴포넌트 입니다. 여기서 useReducer를 사용하여 상태를 정의합니다. 증가 버튼과 감소 버튼의 onClick 속성에 dispatch를 실행시키는 함수를 등록합니다. dispatch는 countReducer함수를 실행시키는 함수로, 인자로 상태를 업데이트 시켜줄 때 필요한 정보들을 전달합니다. 해당 정보는 { type: 기능(함수)명, payload: 재료 }의 형태로 전달하는 것이 관례입니다. 이것은 reducer 함수의 2번째 인자인 action에 전달되어 실행됩니다. 아래 countReducer 코드에서 설명하겠습니다.
import { useReducer } from 'react';
import { countReducer } from './reducer/countReducer.ts';
function App() {
//초기값을 0으로 하는 count 상태를 countReducer를 통해 관리
const [count, dispatch] = useReducer(countReducer, 0);
return (
<>
<h1>Count:{count}</h1>
{/* dispatch의 인자는 { type: 함수명(기능) , payload: 필요한 재료 데이터 }의 형태가 관례입니다. */}
<button onClick={() => dispatch({ type: 'increase', payload: 2 })}>
증가(+2)
</button>
<button onClick={() => dispatch({ type: 'decrease', payload: 1 })}>
감소(-1)
</button>
</>
);
}
export default App;
2. countReducer 함수
countReducer 함수는 dispatch에 의해 실행되고 상태를 업데이틑 하는 함수입니다. 두 개의 매개변수를 가지는데, 첫 번째 매개변수로 state를 받고, 두 번째 매개변수로 action을 받습니다. 이 action이 바로 dispatch 함수의 인자로 전달된 값입니다.
코드로 살펴보면 증가 버튼을 클릭하면 { type: 'increase', payload: 2 } 값이 countReducer의 action값으로 전달되어 실행되어 state값에 2만큼을 더한 값이 리턴되고 그 값으로 count 상태가 업데이트됩니다.
export type TCountAction = {
type: 'increase' | 'decrease';
payload: number;
};
export const countReducer = (state: number, action: TCountAction) => {
switch (action.type) {
case 'increase':
return state + action.payload;
case 'decrease':
return state - action.payload;
default:
return state;
}
};
Demo
https://stackblitz.com/edit/vitejs-vite-epvzuj?file=src%2FApp.tsx
해당 글은 [유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 수업내용을 바탕으로 작성되었습니다.
'개발공부' 카테고리의 다른 글
[React] 불필요한 리렌더링을 방지하는 방법 : [유데미x스나이퍼팩토리] 프로젝트 캠프 Next.js 2기 (0) | 2024.08.04 |
---|---|
[자바스크립트] 비동기 처리를 어떻게 할까? (1) | 2024.07.21 |
[React Hook Form] 선택 이유와 사용법 (0) | 2024.07.12 |
[React] Context Api와 createPortal로 모달 핸들러 만들기 (0) | 2024.03.20 |
[CSS] flex 속성 정리 (0) | 2023.05.17 |