돌멩이 하나/에러는 미래의 연봉

[React] useEffect hook에서 async/await 쓰는 방법

미래에서 온 개발자 2023. 1. 9. 23:00

📍문제 상황

Login 컴포넌트에서 로그인 버튼을 누르면 GitHub OAuth 인증을 통해 Github resource server에서 사용자 정보를 받아와 Mypage 컴포넌트에서 사용자 정보를 이용해 화면을 그려줘야 했다.

 

Login 컴포넌트 화면
Mypage 컴포넌트 화면

 

이 과정에서 Mypage 컴포넌트에서 useEffect hook를 이용해 의존성 배열 자리에 빈 배열을 넣어서 Mypage 컴포넌트가 처음 렌더링 될 때 hook의 callback 함수에 axios post 요청을 해서 사용자 정보를 받아오려고 했다. 

 

  useEffect(async () => {
    const res = await axios.post("http://localhost:4000/userinfo", {
      accessToken,
    });

    setGithubUser(res.data.githubUserData);
    setServerResource(res.data.serverResource);
    setIsLoading(false);
  }, []);

 

그랬더니 위의 이미지와 같이 화면에 사용자 정보는 담겼는데 콘솔 창에 빨갛게 경고가 표시됐다. 여기까지는 그냥 단순히 경고였지만 문제는 Mypage 컴포넌트에서 로그아웃 버튼을 누르면 Mypage 컴포넌트가 destroy 되고 다시 초기 화면인 Login 컴포넌트가 화면에 떠야 했는데, 로그아웃 버튼을 누르면 화면에 아무것도 표시되지 않는 빈 화면으로 바뀌어버렸다.

 

 

경고의 내용을 찬찬히 읽어보니 useEffect hook을 useEffect(async () => ... )로 쓰고 있거나 useEffect hook이 Promise를 리턴하는 게 문제란다. 위의 코드에서 보다시피 나의 경우는 전자였다. 경고 메시지의 하단에는 hook에서 data fetching을 하는 법에 대해서 알아보라며 링크도 주는데, 이 링크까지 갈 것도 없이 바로 다음 줄에서 친절하게 어떻게 고쳐야할지 알려주고 있다. 

 

📍 해결책

useEffect hook의 callback 함수 안에서 async 함수를 쓰고, 해당 함수를 바로 호출한다. 

 

  useEffect(() => {
    async function requestUserInfo() {
      const res = await axios.post("http://localhost:4000/userinfo", {
        accessToken,
      });

      setGithubUser(res.data.githubUserData);
      setServerResource(res.data.serverResource);
      setIsLoading(false);
    }
    requestUserInfo();
  }, []);

 

위와 같이 리액트가 하란대로 코드를 수정했더니 콘솔 창이 바로 깨끗해지고, 로그아웃 버튼을 누른 후에도 초기 화면으로 정상적으로 돌아갔다. 리액트 이 녀석 의외로 상냥한 걸... 

 

 

📚 참고자료

 

How to fetch data with React Hooks

A tutorial on how to fetch data in React with Hooks from third-party APIs. You will use state and effect hooks for the data request from a real API ...

www.robinwieruch.de