state 관리를 도와준다.
useState보다 더 복잡한 state 관리할 때 사용
여러 state가 함께 바뀌거나 관련된 경우
-> useState는 관리가 어려워 오류발생 가능성 높음.
const [enteredEmail, setEnteredEmail] = useState("");
const [emailIsValid, setEmailIsValid] = useState();
2개의 state 모두 사용자가 입력한 내용에 따라 바뀌지만 서로 다른 변수다.
이런 경우에 useReducer 사용하는 게 좋다.
﹥ 다른 state를 기반으로 하는 state를 업데이트하면 그 경우엔 하나의 state로 병합하는 게 좋다. 그냥 이메일 state 값과 유효성을 한 객체로 만들면 됨
-> 근데 state가 복잡해지고 여러개가 결합되면 useReducer 고려해보자.
const [state, dispatchFn] = useReducer(reducerFn, initialState, initFn);
const emailReducer = (state, action) => {
if(action.type === 'USER_INPUT') {
return {value: action.val, isValid: action.val.includes('@')} // value, isVald를 모두 업데이트함 USER_INPUT 액션을 받을때마다.
}
return {value: '', isValid: false}
// 리듀서로 오는 다른 모든 액션이면 이걸 리턴
};
// 함수 바깥에 만드는 이유 : 리듀서 함수 내부에서는 컴포넌트 함수 내부에 만들어진 어떤 데이터도 필요하지 않기 때문.
// 리듀서 함수 내부에서 요청되고 사용되는 데이터는 모두 이 함수로 전달된다.
// 리듀서 함수는 최신 state, 디스패치된 액션 두개의 매개변수를 받는다.
const Login () => {
const [emailState, dispatchEmail] = useReducer(emailReducer, {value: '', isValid: false});
// 이제 enteredEmail -> emailState.value
// emailIsValid -> emailState.value 로 바꿀 수 있음. 더이상 사용하지 않음.
// 액션을 디스패치한다.
const emailChange = (e) => {
dispatchEmail({type: 'USER_INPUT', val: event.target.value}); // 보통은 객체가 들어감.
// 액션에 페이로드 추가 가능. 사용자가 입력한 내용을 저장하고 싶으니 추가한다.
}