지금까지 useEffect를 사용해 왔지만 동작 순서나 의존성 배열에 대해 제대로 알지 못하고 사용해왔으므로,
이를 다시 한 번 정리해 보았다.
리액트는 배경에서 자바스크립트 변수로 state를 관리한다.
즉 애플리케이션을 다시 로드하면 전체 리액트 스크립트가 다시 시작되고(초기화) 따라서 얻은 모든 state는 제거된다.
그러므로 로그인 유지와 같이 state를 유지해야 할 경우를 위해 로그인 정보를 브라우저 저장 공간인 로컬 스토리지 또는 쿠키에 저장시키곤 한다.
참고로 이 브라우저 저장 공간은 리액트와는 아무 관련이 없다.

localStorage.setItem는 두가지 인자가 필요한데, 둘 다 문자열로 지정한다.
application 탭을 보면 다음과 같은 키 밸류를 확인할 수 있다.

앱이 다시 시작된다면 로컬 저장소의 키 밸류를확인한다.
이를 확인하기 위해 useEffect를 사용한다.
위의 코드와 같이 의존성을 빈배열로 두면 컴포넌트가 초기에 실행되었을 때 실행된다.
useEffect는 특정 시점에 해당 함수 안의 내용을 실행할 수 있기 때문이며 위의 코드는 앱이 처음 시작 됬을 때의 시점에 해당 함수 안의 내용을 실행한다.
앱이 초기에 실행되면 useEffect의 내용이 실행되고 state를 업데이트하고 로그인이 유지된다.
만약 이 코드를 일반적인 함수로 선언한다면
초기화 -> 로그인 유지를 위한 state 변경 -> 컴포넌트 리렌더링 -> 로그인 유지를 위한 state 변경 ...
의 무한 루프를 발생한다. 이를 useEffect가 막아주는 것이다.

setFormIsValid는 이메일과 패스워드의 유효성을 검사하는 state이다.
enteredEamil 또는 enteredPassword가 마지막 컴포넌트 렌더링 주기에서 변경된 경우에만 실행하도록 할 수 있다.
이 두가지가 변경되지 않을 경우 이 함수는 실행되지 않는다.
useEffect는 사이드이펙트를 처리하기 위해 존재한다.
http 리퀘스트 등 뿐만아니라 입력 후 응답 액션 실행 또한 사이드 이펙트이다.
useEffect는 이러한 사이드이펙트, 즉 무언가에 대한 응답으로 실행되는 코드를 다루는데 도움이 된다.

클린업 코드는 첫 번째 사이드이펙트가 실행되기 전에는 실행되지 않는다.
useEffect에서 setTimeout api함수를 이용해서 특정 시간이 지난 후 응답 액션이 실행되도록 할 수 있다.
이 때 액션은 1회만 실행되기 때문에 http 리퀘스트 등을 사용하기 좋다.
이 때 setTimeout을 한 뒤 clearTimeout으로 해당 타이머함수를 제거해 주어야 한다.
이 때 클린업 코드를 사용한다.