본문 바로가기

공부기록/[강의노트] Udemy React 완벽가이드 101~200

# 119 [udemy React 완벽 가이드 노트] useEffect 사용하기

우리는 백엔드 서버에 

이메일과 비밀번호의 유효성 검사를 위해 http 리퀘스트를 보낼 수 있다. 

 

실제로는 로그인하면 

백엔드 서버에 리퀘스트를 보내서 로그인 데이터를 가져온다. 

(예를들어 사용자가 인증된 것으로 식별하는 토큰)

뒤에서 자세히 공부 하기로 한다. 

 

목표 : 로그인 인증상태에 있고 싶다. 


 

현재 인증상태는 리액트에 의해서 state로 관리되고 있다. 

리액트가 자바스크립트 변수로 관리하는 중 

 

새로고침하면 리액트가 다시 실행되어 모든 변수는 사라짐 

(데이터를 잃음)

 

앱이 시작될 때마다 데이터가 유지되었는지 확인하여 

그렇다면 다시 유저를 로그인 시킨다. 

 

이 때 사용하는 것이 useEffect 

 

    localStorage.setItem('isLoggedIn', '1')

첫번째 식별자와 두번째 식별자 모두 string 형태로 집어넣는다.

 

 

 

새로고침해도 저장되어있다면 isLoggedIn 을 true로 하고싶다. 


그렇게 다시 로그인 하지 않아도

로그인 후 화면을 렌더링 하게 만들어주고 싶은것이다. 

 

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const storedInform = localStorage.getItem("isLoggedIn");

  if (storedInform === "1") {
    setIsLoggedIn(true);
  }

  const loginHandler = (email, password) => {
    // We should of course check email and password
    // But it's just a dummy/ demo anyways
    localStorage.setItem("isLoggedIn", "1");
    setIsLoggedIn(true);
  };

  const logoutHandler = () => {
    setIsLoggedIn(false);
  };

  return (
    <React.Fragment>
      <MainHeader isAuthenticated={isLoggedIn} onLogout={logoutHandler} />
      <main>
        {!isLoggedIn && <Login onLogin={loginHandler} />}
        {isLoggedIn && <Home onLogout={logoutHandler} />}
      </main>
    </React.Fragment>
  );
}

 

 

무한루프를 빠져나와보자


그런데 위 코드는 무한루프 될 코드가 있다. 

 

바로 

  if (storedInform === "1") {
    setIsLoggedIn(true);
  }

이것... 

만약 storedInform이 1이면  다시 setState함수를 부르고 

그렇게되면 재 렌더링 되고 

또 if함수 실행되고 setState함수 부르고 

재렌더링 되고

 

...

 

무한루프 되지 않으려면 useEffect를 써보자.


useEffect(() => {
    const storedInform = localStorage.getItem("isLoggedIn");
    if (storedInform === "1") {
      setIsLoggedIn(true);
    }
    
  }, []);

이렇게 . 

이 함수는 App안에 들어있는데 

모든 컴포넌트 재평가 후에 실행된다. 

 

그러니까,

 

맨처음 컴포넌트가 평가되고 렌더링 된다 => useEffect함수가 실행된다 => deps가 변경된 경우 함수가 재실행된다.

 

useEffect가 실행될 때 : dependencies가 변경될 때


 

1.    dependencies가 [ ]  인 경우 


가장 처음 앱이 실행될 때만 실행          (dependencies가 변경된 것으로 간주되기 때문)

그 이후로는 의존성이 변경되지 않음 (비어있기 때문)

 

 

 

2. dependencies가 비어있는 경우


매번 state가 변경될 때마다 실행된다. 

그냥 다이렉트로 적은것과 다를바가 없다. 

 

 

 

3. dependencies가 들어있는 경우


email과 password changeHandler에서 각각 똑같은 로직을 가지고 

행했던 setFormIsValid.

  const emailChangeHandler = (event) => {
    setEnteredEmail(event.target.value);

    setFormIsValid(
      event.target.value.includes('@') && enteredPassword.trim().length > 6
    );
  };

  const passwordChangeHandler = (event) => {
    setEnteredPassword(event.target.value);

    setFormIsValid(
      event.target.value.trim().length > 6 && enteredEmail.includes('@')
    );
  };

이것을 useEffect에서 하나로 묶어 

폼이 유효한지 아닌지 표시해보기로 하자.

 

이때 email이나 password가 변경될 경우에만 실행되어야 한다. 

 

useEffect(() => {
    setFormIsValid(
      enteredEmail.includes("@") && enteredPassword.trim().length > 6
    );
  }, [setFormIsValid, enteredEmail, enteredPassword]);

이러면 setFormIsValid가 실행될때나 email이나 password가 변경될 경우에만 실행된다.

setFormIsValid는 생략해도 되는데 변경되지 않도록  react에 의해 설정되어있기 때문이다.

 

 

그런데 헷갈리지 말것은 useEffect는 사이드이펙트를 처리하기 위해 존재한다. 


http 리퀘스트나 키입력을 듣고 데이터를 저장하는 것 등이 그 예이다. 

이메일과 패스워드를 제출할 때

그 입력에 대한 응답으로 폼의 유효성을 체크하는 것도 사이드 이펙트중 하나다

(사용자 입력 데이터의 사이드이펙트)

 

무언가에 대한 응답으로 실행되는 코드를 다루는데 도움이 된다. 

어떤 액션에 대한 응답으로 실행되는 액션 그것이 사이드이펙트다. 

 

 

dependencies로 추가하지 않아도 될것들


상태 업데이트 기능 

set함수 같은 것들 (변경되지 않도록 react에 의해 보장되어있음)

 

"내장" API 또는 함수

fetchlocalstorage 같은 것들

이러한 브라우저 API/전역 기능은 React 구성 요소 렌더링 주기와 관련이 없으며 변경되지 않는다.

 

변수나 함수

이러한 함수 또는 변수도 구성 요소 함수 내부에서 생성되지 않으므로 변경해도 구성 요소에 영향을 주지 않는다.