useEffect(() => {
const identifier = setTimeout(() => {
console.log('Checking form validity!');
setFormIsValid(
enteredEmail.includes('@') && enteredPassword.trim().length > 6
);
}, 500);
return () => { // cleanup
console.log('CLEANUP');
clearTimeout(identifier);
};
}, [enteredEmail, enteredPassword]);
useEffect를 최적화하고 이펙트가 불필요하게 실행되는 것을 피하기 위해
함께 사용할 수 있다.
핵심 : 전체 개체 대신 특정 속성을 종속성으로 전달가능.
//객체 디스트럭처링 : useEffect를 최적화하고 이펙트가 실행되는 것을 피하기 위해 필요하다.
const { isValid: emailIsValid } = emailState; //isWalid 추출하고 별명 붙임, 그리고 같은 이름의 새 상수에 저장
const { isValid: passwordIsValid } = passwordState;
useEffect(() => {
const identifier = setTimeout(() => {
console.log('Checking form validity!');
setFormIsValid(
emailIsValid && passwordIsValid
);
}, 500);
return () => {
console.log('CLEANUP');
clearTimeout(identifier);
};
}, [emailIsValid, passwordIsValid]); //값만 변경되고 유효성이 변경되지 않으면 이펙트 다시 실행하지 않음
핵심🎇
📢) useEffect가 언제 실행하는지 순서와 동작하는 방식 알아야함!
- useEffect 함수는 모든 컴포넌트 렌더링 주기 후에 실행된다.
- useEffect의 의존성 추가하면, 의존성에 추가한 state가 변경될 때마다 재실행 된다. 비워두면 처음실행 될 때만 한번 실행됨 (그 이후 렌더링 주기에는 실행x)
- cleanup 함수는 state가 전체적으로 실행되기 전에 실행된다. 그러나 처음 실행되기 전에는 실행 x
모양 🎇
const[state, dispatchFn] = useReducer(reducerFn, initialState, initFn);
import React, {useReducer} from 'react'
const emailReducer = (state, action) => { //매개변수
if (action.type === 'USER_INPUT') { //USER_INPUT 액션 받을 때마다 value와 isValid를 모두 업데이트한다.
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 Login = (props) => {
// const [enteredEmail, setEnteredEmail] = useState('');
// const [emailIsValid, setEmailIsValid] = useState();
const [enteredPassword, setEnteredPassword] = useState('');
const [passwordIsValid, setPasswordIsValid] = useState();
const [formIsValid, setFormIsValid] = useState(false);
const [emailState, dispatchEmail] = useReducer(emailReducer, {
value: '',
isValid: null,
});
const emailChangeHandler = (event) => {
dispatchEmail({ type: 'USER_INPUT', val: event.target.value });
setFormIsValid(
event.target.value.includes('@') && enteredPassword.trim().length > 6
);
};
const passwordChangeHandler = (event) => {
setEnteredPassword(event.target.value);
setFormIsValid(
emailState.isValid && event.target.value.trim().length > 6
);
};
const validateEmailHandler = () => {
dispatchEmail({ type: 'INPUT_BLUR' });
};