컴포넌트를 재활용 할 때, 회원가입 폼에서는 필요하지만, 로그인 폼에서 필요하지 않은 입력창(Input)으로 인해, 공통으로 사용하는 Custom훅에서 Error가 발생하는 경우가 있다.
이럴때에는 continue문으로, 회원가입 폼에서만 사용하는 Input만 filtering할 수 있다.
//Auth component
//business logic
const [formState, inputHandler,setFormData] = useForm({
email: {},
password: {},
});
const [isLogin, setIsLogin] = useState(true);
const authSubmitHandler = (e) => {
e.preventDefault();
console.log(formState.inputs);
};
const switchSignHandler = () => {
if(!isLogin){
setFormData({
...formState.inputs,
name: undefined
},formState.inputs.email.isValid && formState.inputs.password.isValid)
}else{
setFormData({
...formState.inputs,
name:'',
isValid:false
},false)
}
setIsLogin((prev) => !prev);
};
//presentation
return (
<div className="w-11/12 max-w-md my-28 mx-auto text-center">
<h2 className='text-white text-center'>Open the public that place just only you know</h2>
<hr />
<form
className='mb-4'
onSubmit={authSubmitHandler}>
// 삼항연산자로 제어되는 name Input.
// 해당 인풋은 sign-up에만 필요하기에 그냥 사용할 시,
// form을 control하는 custom hook이 정상적으로 작동하지 않는다
{!isLogin && (
<Input
element="input"
id="name"
type="text"
label="Nickname"
validators={[VALIDATOR_REQUIRE()]}
errorText="Please write your name"
onInput={inputHandler}
/>
)}
<Input
element="input"
id="email"
type="email"
label="E-Mail"
validators={[VALIDATOR_EMAIL()]}
errorText="Please enter a valid e-mail"
onInput={inputHandler}
/>
<Input
element="input"
id="password"
type="password"
label="Password"
validators={[VALIDATOR_MINLENGTH(10)]}
errorText="Please enter a valid password, at leat 10 words"
onInput={inputHandler}
/>
<Button type="submit" disabled={!formState.isValid}>
{isLogin ? '로그인' : '회원가입'}
</Button>
</form>
<Button inverse onClick={switchSignHandler}>
{isLogin ? '회원가입' : '로그인'}하러 가기
</Button>
</div>
);
// custom hook
const formReducer = (state,action) => {
switch (action.type) {
case 'INPUT_CHANGE':
let formIsValid = true;
for(const inputId in state.inputs){
// continue문을 통해, inputs의 name의 value가 falsy값이라도
// 계속 나머지 validation을 진행할 수 있게 만든다.
if(!state.inputs[inputId]){
continue;
}
if(inputId === action.inputId){
formIsValid = formIsValid && action.isValid;
}else{
formIsValid = formIsValid && state.inputs[inputId].isValid
}
}
return {
...state,
inputs: {
...state.inputs,
[action.inputId]:{ value: action.value, isValid:action.isValid}
},
isValid: formIsValid
}
case 'SET_DATA':
return {
inputs:action.inputs,
isValid:action.formIsValid
}
default:
return state;
}
}