useEffect hook은 내장 후크입니다.
컴포넌트 함수 내부에서 실행할 수 있는 또 다른 함수입니다.
이 함수는 사이드 이펙트(side effect)를 처리하기 위해 존재합니다.
useEffect는 두 개의 매개변수와 함께 실행됩니다. 첫 번째 인수는 함수입니다. 모든 컴포넌트 평가 후에 실행되어야 하는 함수입니다. 지정된 의존성이 변경된 경우에도 실행됩니다.첫 번째 인수는 함수입니다. 두 번째 인수는 지정된 의존성을 두 번째 인수로 넣어줘야 합니다.
effect 함수에서 사용하는 "모든 것"을 종속성으로 추가해야 합니다. 즉, 거기에서 사용하는 모든 상태 변수와 함수를 포함합니다.
하지만 몇 가지 예외가 있습니다.
정리하면 컴포넌트가 다시 렌더링 되어서 변경이 될수 있는 것들을 종속성 배열에 추가해야 합니다. 그렇기 때문에 컴포넌트 함수에 정의된 변수나 상태, 컴포넌트 함수에 정의된 props또는 함수는 추가되야 합니다.
useEffect(() => {...}, [ dependencies]);
사용자가 이메일과 비밀번호를 입력할 때마다 유효한지 검사하는 것인데 실제로 사용자가 입력을 하나하나 할 때마다 데이터를 서버에 보내서 유효한지 확인한다고 하면 효율성이 매우 떨어질 것입니다. 그렇다면 사용자가 입력하는 것을 멈추고 일정 시간이 지나고 확인한다면 더 효율적일 것입니다. 이것은 디바운싱이라고 합니다. 브라우저에 내장된 함수인 setTimeout을 사용하여 쉽게 구현할 수 있습니다.

useEffect(() => {
setTimeout(() => {
console.log("유효한지 검사");
setFormIsValid(
enteredEmail.includes("@") && enteredPassword.trim().length > 6
);
}, 500);
}, [enteredEmail, enteredPassword]);
하지만 여기서 중요한 건 타이머를 입력마다 저장한다는 것입니다. 저희는 다음에 키가 입력되면 지워야 합니다. 이때 클린업 함수를 사용해야 합니다. 아래 코드처럼 화살표 함수를 하나 반환합니다. 이 함수는 언제 실행이 되나면 useEffect 함수가 처음 실행되는 경우를 제외하고 useEffect 함수 실행되기 전 클린업 함수가 실행됩니다. 또한 useEffect를 사용한 컴포넌트가 DOM에서 마운트 해제될 때마다 실행됩니다.
setTimeout()함수는 timer를 식별하는 timeoutId값을 반환하는데 이 반환값과 clearTimeout()함수를 이용하여 저장된 타이머를 지울 수 있습니다.
useEffect 함수가 실행되기 전 실행되는 클린업 함수를 사용하여 새로운 타이머를 저장하기 전에 마지막 타이머를 지우는 것입니다.
useEffect(() => {
const identifier = setTimeout(() => {
setFormIsValid(
enteredEmail.includes("@") && enteredPassword.trim().length > 6
);
}, 3000);
return () => {
console.log("Clean Up");
clearTimeout(identifier)
}
}, [enteredEmail, enteredPassword]);