[React] 인증 페이지 라우터에서 리다이렉트하기

게코젤리·2023년 3월 24일
0
post-custom-banner

특정 경로에 진입시 사용자 인증이 되어있지 않으면 리다이렉트하는 기능이 필요했다.

처음에 구현한 것은 아래와 같이
'/profile'의 Profile 컴포넌트가 마운트 됐을 때 store의 isLoggedIn를 참조하여 !isLoggedIn일시 '/auth'로 이동하게 했다. 문제는 없지만 이러한 페이지가 많을 경우에는 유지보수에 좋지 못할 수도 있다.

function Profile() {
  const { isLoggedIn } = useSelector((state: RootState) => state.init);
  // 비 로그인 시 home으로 이동
  useEffect(() => {
    if (!isLoggedIn) {
      navigate('/auth');
    }
  }, [isLoggedIn]);
}

다음은 PrivateRoute를 활용하는 방법이다. 간단하게 isLoggedIn만 확인하고 navigate시키는 장치를 원하는 컴포넌트에 씌워준다고 생각하면 된다.
children을 props로 받아와야하기 때문에 ReactNode를 import해준다.

// PrivateRoute.tsx
import { ReactNode, useEffect } from 'react';
function PrivateRoute({ children }: { children: ReactNode }) {
  const { isLoggedIn } = useSelector((state: RootState) => state.init);
  const navigate = useNavigate();

  useEffect(() => {
    if (!isLoggedIn) {
      navigate('/auth');
      alert('로그인이 필요합니다.');
    }
  }, [isLoggedIn, navigate]);

  if (!isLoggedIn) {
    return null;
  }

  return <>{children}</>;
}
export default PrivateRoute;

// App.tsx
  <Wrapper>
    <Routes>
      <Route path="/" element={<Navigate to="/home" />} />
      <Route path="/home" element={<Home />} />
      <Route path="/rate" element={<PrivateRoute><Rate /></PrivateRoute>} />
      <Route path="/auth" element={<Auth />} />
      <Route path="/profile" element={<PrivateRoute><Profile /></PrivateRoute>} />
      <Route path="/*" element={<NotFound />} />
    </Routes>
  </Wrapper>

'/auth' 페이지에선 반대되는 기능을 활용할 수 있도록 다음과 같이 수정했다.

useEffect(() => {
    if (authMatch && isLoggedIn) {
      navigate('/home');
      return
    } 

    if (authMatch && !isLoggedIn) {
      return;
    }

    if (!isLoggedIn) {
      navigate('/auth');
      alert('로그인이 필요합니다.');
    }
  }, [isLoggedIn, navigate, authMatch]);

  if (!authMatch && !isLoggedIn) {
    return null;
  }

  return <>{children}</>;

계속 느끼는 건데 리액트는 정말 분리와 재사용의 연속인 것 같다.

post-custom-banner

0개의 댓글