상태관리를 위한 방법 중 하나로 useState와 비교하여 사용할 수 있다.
대표적인 특징으로는 다음과 같다.
1. 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리할 수 있다.
2. 업데이트 로직을 컴포넌트의 바깥에서 작성할 수 있다.
3. 다른 파일에 작성한 후 불러와서 사용할 수 있다.
React의 큰 특징으로는 state가 변경되면 새롭게 변경된 부분을 표현하기 위해 모든 컴포넌트를 다시 실행하게 된다. 스케일이 작은 프로젝트의 경우 문제가 되지않으나, 스케일이 커지고 이용자가 증가하는 등 트래픽이 증가할 경우 최적화에 신경쓸 수 밖에 없다. 이럴 경우 필요에따라 부분적으로 useState대신 useReducer를 사용하여 상태관리를 할 수 있다.
□ 언제 사용?
최적화를 위한 구분과 사용이므로 정답은 없다.만약 컴포넌트에서 관리하는 값이 한가지이고, 단순한 숫자, 문자열과 같은 기본 값의 타입을 보인다면 useState가 직관적이고 편하다.
이와 반대로 컴포넌트에서 관리하는 값이 여러가지이고, 연결되어있는 값이라 상태의 구조가 보다 복잡하고 얽혀있다면 useReducer로 관리하는 것이 편할 것이다.
※ setter 함수가 많다면 고민해보자.
□ useReducer를 만들기 위한 필수항목 4가지
1. useReducer 함수
2. state
3. dispatch와 이벤트간의 설정 및 연결
4. 컴포넌트 외부에서 업데이트할 state와 reducer 간의 로직 설정
형태는 다음과 같다.
const [number, dispatch] = useReducer(reducer, 0)
const [상태, 액션을 발생시킬 함수] = useReducer(reducer함수, 초기상태)
※ 이때, dispatch, reducer, 초기상태는 알맞게 변경가능하다.
□ dispatch 기본형태 : dispatch({ type : '구분되는 값' });
위의 형태에서 const [number, dispatch]
의 dispatch와 이름이 같아야 한다.
□ 이벤트 함수와 연결시
기본형태 : 함수 = () => {dispatch({ type : '구분되는 값' })};
□ state를 업데이트할 reducer 작성시
기본 형태 :
function reducer(state, action){
switch(action.type) {
case '구분되는 값-1' : {
return (state변경);
}
case '구분되는 값-2' : {
return (state변경);
}
}
}
위의 형태에서 const [number, dispatch] = useReducer(reducer, 0)
의 reducer와 이름이 같아야한다.
function reducer에서 받는 state는 const로 선언했던 state값이다. 즉, 위의 예시에선 number가 되는 셈이다.
action의 경우 dispatch({ type : '구분되는 값' }) 에서의 type을 의미한다.
App.tsx라는 컴포넌트에서 초기값으로 주어진 숫자에 +1, -1을 해주는 함수를 작성해본다고 가정해보자.
import React, {useReducer} from 'react';
//App 컴포넌트 외부에서 reducer함수 작성
function CountReducer(number, action) {
switch(action.type){
case "PLUS" : {
return number + 1;
};
case "MINUS" : {
return number - 1;
};
default : return number;
};
};
export default fucntion App(){
// useReducer 함수 선언
const [number, CountDispatch] = useReducer(CountReducer, 0);
// 이벤트함수와 dispatch 연결, 적용
const onPlus = () => {
CountDispatch({type :"PLUS"})
}
const onMinus = () => {
CountDispatch({type :"MINUS"})
}
// 함수 적용
return (
<div>
<h2>{number}</h2>
<button onClick={onPlus}> +1 </button>
<button onClick={onMinus}> -1 </button>
</div>
);
}