ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 로그인 할 때 비동기 처리가 필요하다
    Error records 2022. 1. 31. 13:42

    로그인을 위해 유저 정보를 받아온 뒤 에 스테이트에 저장하려고 했다.

    useEffect 를 써서 userInfo res를 객체를  setState를 해줬는데도 결과는 빈배열...이 계속 찍히는 것이었다. 이걸 해결하는데 거의 반나절이 걸렸으므로 해결방법을 써본다...

     

    실행순서와 원인:

     

    useEffect=>(axios.get response 데이터를 가지고+setState())를 실행시키지만 setState는 response가 올때까지 기다려 주지 않는다. 그냥 빈 객체로 초기화 시켜버린상태이고(setState감지를 못함? 혹은 그냥 setState를 실행했지만 변화가 없어서 그냥 턴이 넘어감?) 데이터가 다 받아진 다음에 다시 setState를 하려 하지만,  useEffect가 재 실행되지는 않는다(빈 의존성 배열이므로 이미 최초에 한번 실행함). 

    요약하면, useEffect안에 setState가 들어있는데 useEffect를 두번 실행 할 수 없으니 data가 받아진 후에 setState를 실행 할 수가 없는 것이다.

     

    거의 해결하는데 거의 하루가 걸렸다(중간에 몇시간 하다가 안되서 짜증나서 저녁에 푹 쉬어버렸다 ㅎㅎ...쉬면서 누워서 휴대폰하다가 문득 해결법이 떠오름)

     

    이를 해결하기 위한방법을 두가지 찾았다.

    1. 의존성 배열사용:

    의존성 배열에 state의 값을 넣어줘서 state가 변하면 다시 useEffect를 재실행. 스테이트가 변하므로 컴포넌트 재 랜더링을 시키는 방법

     

    2. 비동기 함수(promise, async)를 사용:

    비동기 함수를 사용해서 useEffect내에서 데이터를 불러올때까지 setState를 실행하지 않는다 데이터가 받아 진 뒤 setState를 하고(물론 이는 state의 변화가 있기 때문에 바로 화면을 재랜더링 시킨다). 이는 빈 의존성 배열로도 같은 결과를 낼 수 있다. 쓸 때 없이 계속 데이터를 안불러와도 되므로 이방법이 더 좋아보인다.

     

    참고로 useEffect안에서 사용하려면 다음과 같이 따로 함수를 하나 만들어 준 뒤 그 안에서 사용해야한다.

     

     

     

    로그인할때 이런식으로 비동기 처리를 해주면 의존성 배열에 빈값을 넣어도 reponse가 바로 setState에 반영이 된다.

    만약에 이런 비동기 처리를 해주지 않는다면 컴포넌트가 state의 값을 가지고 렌더링을 하고난 뒤 데이터가 fetch되어지기때문에 빈 의존성배열로는 업데이트가 안된다(처음에 한번만 useEffect를 실행)

     

     

     

     

Designed by Tistory.