이 글은 단순히 리액트 공식 문서를 읽고 베꼈을 뿐이다!! 학습 목적이라면 공식 문서를 보는 걸 추천한다.
공식 문서
https://react.dev/learn/extracting-state-logic-into-a-reducer
Extracting State Logic into a Reducer – React
The library for web and native user interfaces
react.dev
reducer로 로직을 통합하기
- 컴포넌트가 점점 더 복잡해지면 컴포넌트의 상태 업데이트 로직들을 한눈에 보기 힘들어짐
- reducer를 이용하면 이런 로직들을 접근이 쉬운 하나의 외부 함수로 만들 수 있음
useState
에서 useReducer
로 옮기는 세 단계
1. 상태 설정에서 행동(action) 보내기로 바꾸기
- 모든 상태 설정 로직을 지우기
- 대신 '어떤 행동을 했길래' 상태가 설정되어야 하는지 생각하기
- 그리고
dispatch()
함수의 인자에 어떤 일이 일어났는지 알려줄 수 있는 최소한의 정보들을 같이 담기 - 이 정보들을 action object라고 함
- action object의 형태에는 제약이 없음: 컨벤션으로 행동의 이름을
type
으로 주는 경우가 일반적
const addNewTask = (text) => {
dispatch({
type: 'added',
text,
});
}
2. reducer 함수 만들기
- 상태 관련 로직들을 넣는 곳
- 인자로 두 개를 받음: 현재 상태, action object
- 반환값은 하나: 다음 상태
- 인자로 상태를 받기 때문에 컴포넌트 밖에 정의 가능
- if/else 또는 switch-case를 통해 action type별로 나누어 진행
- 이름이 'reducer'인 이유: 배열의
reduce()
메서드와 같은 작동 원리임━이전 상태와 현재 값을 받아서 다음 상태를 반환
3. 컴포넌트에서 reducer 쓰기
import { useReducer } from 'react';
useState
가 있는 부분을const [myState, dispatch] = useReducer(myStateReducer, myInitialState);
이렇게 바꾸기
- 이런 방식으로 컴포넌트 로직의 관심사 분리 가능
- 이벤트 핸들러들이 '무엇이 일어났는지'만 알면 되고 '어떻게 상태를 바꿔야 하는지'는 몰라도 되게 할 수 있음
useState
vs useReducer
- 코드 길이
- 일반적으로 useState가 더 짧음
- 많은 이벤트 핸들러들이 상태 변경에 같은 로직을 사용하는 경우 useReducer로 코드 길이를 줄일 수 있음
- 가독성
- useState는 상태 업데이트가 간단할 때는 보기 편한데 복잡해질수록 어려움
- useReducer는 행동과 로직을 분리하여 이벤트 핸들러에선 행동만 볼 수 있어서 좋음
- 디버깅
- useState를 쓸 경우 어디에서, 왜 상태 변경 버그가 났는지 찾기 어려울 수 있음
- useReducer는 상태 변경 로직이 한 군데에 있고, action type 때문에 범인 찾기가 상대적으로 쉬움
- 테스팅
- reducer 함수는 컴포넌트에 의존하지 않는 순수함수이기 때문에 테스트가 가능함
- 개인 취향
reducer 잘 만들기
- reducer는 순수해야 함
- 각 action은 하나의 사용자 상호작용만을 나타내야 함 (설령 그 행동이 여러 개의 데이터를 바꾸더라도)
'리액트 공식 문서 읽기' 카테고리의 다른 글
22화: Scaling Up with Reducer and Context (0) | 2023.06.18 |
---|---|
21화: Passing Data Deeply with Context (0) | 2023.06.18 |
19화: Preserving and Resetting State (0) | 2023.06.17 |
18화: Sharing State Between Components (2) | 2023.06.17 |
17화: Choosing the State Structure (0) | 2023.06.17 |