배경설명
- react
- react-router
- graphql
- jwt
관리자 사이트에 들어갈때, 로그인을 해야만 들어갈 수 있게 한다.
localStorage에 로그인 정보가 없으면, login페이지로 넘어가도록 한다.
문제상황
처음에 myAdmin.com/ 요기가 Admin page, myAdmin.com/login 요기가 login page다. /로 들어왔을때 로그인 정보가 없으면 /login으로 redirect 시켰다. 그런데 다음과 같은 에러가 나왔다.
Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops
const AuthRedirect: FC<VC.AuthRedirectProps> = ({destination}) => {
return <Route render={
(props) => (<Redirect to={{ pathname: destination, state: { from: props.location } }} />)}
/>;
}
export default AuthRedirect;
const AuthRoute: FC<VC.AuthRouteProps> = ({render, component: Component, redirectTo, ...rest}): ReactElement => {
// localStorage에서 accessToken이 있는지 확인함. 없으면 바로 redirect갈긴다
let accessToken = localStorage.getItem(ACCESSTOKEN_ID);
console.log("access token : ", accessToken);
const redirect = <AuthRedirect destination={redirectTo}></AuthRedirect>
console.log("REDIRECT입니당~");
if (accessToken == null) return redirect;
const { loading, error, data } = useQuery(VERTIFY_ACCESS_TOKEN, {
variables: { token: accessToken }
});
if (loading) return <div>Loading...</div>;
if (error) {
return <div>Has Error !</div>
}
return (
<Route
{...rest}
render={(props) =>
render ? (
render(props)
)
: Component ? (
<Component {...props}></Component>
)
: ({})
}
/>
);
}
export default AuthRoute;
<Switch>
<Route path="/">
<AuthRoute component={Admin} redirectTo={"/login"}></AuthRoute>
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
처음에 myAdmin.com/으로 들어오니까 AuthRoute가 그려지고 -> Admin이 그려지는데, if (accessToken == null) return redirect;
이 부분에서 딱 걸려서 login 컴포넌트가 그려지는데 login 컴포넌트로 안가고 뭔 Maximum update depth exceeded
에러가 나온다. 왜?…
탐색과정
여기 코드들을 보니까 <Redirect>
를 <Route>
안에 안넣는다. 그냥 바로 <Switch>
안에 넣는다. -> 이건 에러랑 상관없다.
문제는 exact를 안붙인거였다.
해결책 정리
<Switch>
<Route exact path="/">
<AuthRoute component={Admin} redirectTo={"/login"}></AuthRoute>
</Route>
<Route exact path="/login">
<Login />
</Route>
</Switch>
exact가 없으면 myAdmin.com/login으로 가도, /
가 먼저 걸리기 때문에 AuthRoute로 가버린다.