useReducer란 React hook 이다.
useState로 관리하는 state들의 본질이 중복되는 경우가 있다.
다음처럼 두개의 state가 있다.
const [emailValue, setEmailValue] = useState('');
const [emailIsValid, setEmailIsVaild] = useState(false);
이 두 state는 '이메일'에 관련된 서로 다른 값을 각각 관리한다. 이런 경우 위 코드처럼 두개의 useState()를 만들어 각각 관리할 수 있다.
이렇게 하면 두 state를 확실히 구분할 수 있다는 장점이 있다.
하지만 이 두 state 말고도 다른 state들이 추가되면 헷갈릴 수 있다는 단점이 존재한다. 길어진 코드는 덤.
Reducer를 이용하면 여러개의 state를 하나의 state로 묶어서 각각 관리할 수 있다.
useReducer 훅에 대해서 알아보자.
Reducer는 현재 상태(state)와 액션(action) 객체를 파라미터로 받아와서 새로운 상태를 반환하는 함수이다.
위의 이메일에 관련된 상태를 각각의 state로 관리하던 것을 reducer로 다시 만들어보면 다음과 같다.
<1번 코드 블럭>
const emailReducer = (state, action) => {
if (action.type === 'USER_INPUT') {
return { value: action.val, isValid: action.val.includes('@') };
}
return { value: '', isValid: false };
};
<2번 코드 블럭>
const Login = (props) => {
const [emailState, dispatchEmail] = useReducer(emailReducer, {
value: '',
isValid: null,
});
const emailInputHandler = (event) => {
dispatchEmail({type: 'USER_INPUT', val: event.target.value})
}
return ...(JSX)
}
useReducer는 컴포넌트 안에서 사용한다.
useReducer() 함수의 파라미터로는 ('dispatchEmail'로 호출할 함수, 초기값) 을 받는다.
'호출할 함수'는 이 기존값을 업데이트할 함수인데 컴포넌트 밖에서 명명 함수를 선언하여 컴포넌트 안에서 호출하도록 했다.
'초기값'은 여러개의 값의 상태를 관리하기 때문에 객체의 형태로 받았다.
useReducer() 함수의 구조 분해 할당으로 [emailState, dispatchEmail] 변수 두개를 사용할 수 있다.
그 안에서 dispatchEmail()을 호출하고 있다.
dispatchEmail은 객체를 인수로 갖는데, 이는 업데이트할 함수 즉 컴포넌트 밖에서 선언된 emailReducer 함수의 action 파라미터에 들어갈 값이다.
1번 코드 블럭은 원래 useReducer의 인수로 들어갈 업데이트 함수를 컴포넌트 밖에서 명명 함수로 선언한 것이다.
이 emailReducer 함수는 두개의 파라미터 값을 가진다.
이 함수를 실행하면 action과 state의 값에 따라 emailState의 값이 변하게 된다.