기능 공유 및 에러핸들링

[Error]이 Promise<any>는 항상 정의되어 있으므로 이 조건은 항상 true를 반환합니다.

Fo_rdang 2024. 7. 16. 17:18
반응형

1. [의도]

사용자의 로그인 상태를 관리해야한다. 

=> "마이페이지 접근 권한", "리뷰 댓글 권한", "navbar의 로그인, 로그아웃 버튼" 시에 필요함. 

 

1. 백엔드 api를 활용해서 현재 사용자가 로그인 상태인지, 아닌지 확인할 수 있다. 

2. 사용자의 로그인 상태를 매번 서버의 응답으로 판단 하기엔 부담이다. 

3. 사용자가 로그인, 로그아웃 할 때만 서버에 요청을 한 응답 값으로 사용자의 로그인 상태를 변경한다. 

 

장점: redux toolkit 상태 관리를 통해 서버 통신 없이, 해당 상태값에 여러번 접근할 수 있다. 

 

 

2. [문제 상황]

 

3. [문제 코드]

  useEffect(() => {
    let res = checkLogin();//사용자의 로그인 상태 확인하는 함수 
    if (res) dispatch(logIn());//true 값이면 전역적으로 사용자 로그인 상태 true로 관리
    else dispatch(logOut());//false 값이면 사용자 로그인 상태 false로 관리. 
   }
  }, [res]);

 

//사용자 로그인 상태 확인하는 함수 
export const checkLogin = async () => {
  try {
    const res = await axios.get(
      `${process.env.NEXT_PUBLIC_BACKEND_URL}/chkLogin`
    );
    console.log(res.data);
    return res.data;
  } catch (error) {
    console.log(error);
  }
};

 

4. [문제 발생 이유]

1. 사용자가 로그인 상태인지 확인하는 함수인, `checkLogin` 함수는 비동기이다. 

=> 비동기 함수는 `Promise` 객체를 반환한다. 

 

2. `useEffect` 내부에서는 이 함수를 직접 호출해서 반환된 Promise를 기다리지 않고, 이미 존재하는 `Promise`객체를 사용한다.

=> 항상 `true`값으로 평가된다. (Promise 객체는 항상 존재하기 때문에 true로 평가됨)

 

5. [문제 해결 방향]

useEffect 내부에서 checkLogin 함수 호출시 await 키워드를 사용하자. 

 

6. [문제 해결 코드]

useEffect(() => {
    const checkUserLogin = async () => {//비동기 작업을 처리하기 위해 새로운 비동기 함수 정의 
      try {
        let res = await checkLogin(); //checkLogin 함수가 반환하는 Promise를 await으로 기다린다.
        if (res) dispatch(logIn());
        else dispatch(logOut());
      } catch (error) {
        console.log(error);
      }
      checkUserLogin();
    };
  }, [dispatch]); //dispatch 넣는 이유 아래에 설명

 

의존성 배열에 `dispatch`를 포함하는 이유 

: 일반적으로, dispatch 함수는 React Redux의 useDispatch 훅에서 반환되며, 함수 자체가 변경될 가능성은 거의 없지만, 이를 의존성 배열에 포함하는 것은 좋은 관행입니다. 이는 특히 코드가 변형되거나 리팩토링될 때 안전하게 유지하는 데 도움이 됩니다.

//사용자가 로그인 중인지 확인하는 api
export const checkLogin = async () => {
  try {
    const res = await axios.get(
      `${process.env.NEXT_PUBLIC_BACKEND_URL}/chkLogin`
    );
    console.log(res.data);
    return res.data;
  } catch (error) {
    console.log(error);
  }
};

 

반응형