useReducer()
역시 또 하나의 리액트 훅 입니다. state
를 관리한다는 차원에서 useState()
와 비슷하지만, useReducer()
는 객체나, 좀 더 복잡하고 정교한 처리가 가능해집니다.
const [enteredEmail, setEnteredEmail] = useState("");
const [emailIsValid, setEmailIsValid] = useState();
const [enteredPassword, setEnteredPassword] = useState("");
const [passwordIsValid, setPasswordIsValid] = useState();
...
...
state
를 보면, state
끼리 서로 연관된 데이터가 존재합니다. 이를 서로 하나로 묶어서 처리하는 것은 불가능할까요?? 예를 들어
email
과 emailValid
를 하나의 객체로, password
와 passwordValid
를 하나의 객체로 useState()
로 처리하면 어떨까요??
useReducer()
는 reducer 함수를 콜백하는 리액트 훅 입니다.
해당 콜백 함수는 state
와 action
파라미터를 받습니다.
const Login = (props) => {
const [emailState, dispatchEmail] = useReducer(emailReducer, { value: "", isValid: null });
const [passwordState, dispatchPassword] = useReducer(passwordReducer, {
value: "",
isValid: null,
});
...
...
}
useReducer()
의 액션 함수는 업데이트를 위한 정보를 가지고 있습니다. 특별한 규칙은 정해져 있지 않습니다만, 일반적으로 type
을 지닌 객체 속성과 해당 value
값을 대문자로 쓰는 것이 관례인듯 합니다.
const emailReducer = (state, action) => {
if (action.type === "USER_INPUT") {
return { value: action.val, isValid: action.val.includes("@") };
}
if (action.type === "INPUT_BLUR") {
return { value: state.value, isValid: state.value.includes("@") };
}
return { value: "", isValid: false };
};
const passwordReducer = (state, action) => {
if (action.type === "USER_INPUT") {
return { value: action.val, isValid: action.val.trim().length > 6 };
}
if (action.type === "INPUT_BLUR") {
return { value: state.value, isValid: state.value.trim().length > 6 };
}
return { value: "", isValid: false };
};
const Login = (props) => {
...
...
const emailChangeHandler = (event) => {
dispatchEmail({ type: "USER_INPUT", val: event.target.value });
};
const passwordChangeHandler = (event) => {
dispatchPassword({ type: "USER_INPUT", val: event.target.value });
};
const validateEmailHandler = () => {
dispatchEmail({ type: "INPUT_BLUR" });
};
const validatePasswordHandler = () => {
dispatchPassword({ type: "INPUT_BLUR" });
};
}
어떠한 경우 useState()
를 쓰고, 어떠한 경우 useReducer()
를 쓰는 게 좋을까요?? 각각 더 낫다고 생각되는 상황을 적어봅시다.
useState()
useReducer()
useState()
를 사용하면 효율적이지 못한 반복작업으로 코드는 길어지지만, 복잡한 조작 없이 쉽게 코드를 작성할 수 있습니다. 반대로 useReducer()
로 처리한다면 효율적으로 코드를 작성하겠지만, 어떻게 병합하는지 혹은 분리하는지에 따라 코드의 복잡도는 점점 커지게 되겠죠.