我的代码是一个前端,带有来自API的使用axios的请求。它检查cookie以了解是否登录进行身份验证,因此如果没有cookie,它会重定向到主页。
const PrivateRoute: FunctionComponent<AuthProps> = ({
component: Component,
path,
}: AuthProps) => {
const [isAuth, setisAuth] = useState(false);
useEffect(() => {
axios
.get('http://localhost:5000/api/v1/checkcookie', {
withCredentials: true,
})
.then((response) => {
setisAuth(response.data.cookie);
});
});
return (
<Route
render={() => {
return isAuth === true ? <Component /> : <Redirect to="/" />;
}}
/>
);
};
const App: React.FC = () => {
return (
<Router>
<ThemeProvider theme={theme}>
<Layout>
<Switch>
<Route path="/" exact component={Landing} />
<PrivateRoute path="/inquiries" component={Inquiries} />
<PrivateRoute
path="/create-article"
component={CreateArticle}
/>
<Route path="/login" component={Login} />
</Switch>
</Layout>
</ThemeProvider>
</Router>
);
};
但在API发出请求后,isAuth
状态将发生变化,但不会在中发生变化
isAuth === true ? <Component /> : <Redirect to="/" />;
我只想确保它具有最后一个isAuth
值。我如何确保它在达到条件之前改变状态?
尝试添加一个加载状态。
附加说明:
您将需要catch来处理错误。
添加一个空的deps数组以确保它只运行一次。
const PrivateRoute: FunctionComponent<AuthProps> = ({
component: Component,
path,
}: AuthProps) => {
const [isLoading, setIsLoading] = useState(true);
const [isAuth, setisAuth] = useState(false);
useEffect(() => {
setIsLoading(true);
axios
.get('http://localhost:5000/api/v1/checkcookie', {
withCredentials: true,
})
.then((response) => {
setisAuth(response.data.cookie);
})
.catch(console.log)
.finally(() => {
setIsLoading(false);
});
}, []);
if (isLoading) {
return <></>;
}
return (
<Route
render={() => {
return isAuth === true ? <Component /> : <Redirect to="/" />;
}}
/>
);
};
response.data.cookie
是布尔值吗?例如,如果response.data.cookie = '32094jwef9u23sdkf'
,则isAuth === true
将从不评估true
,并且重定向将始终呈现。此外,从不直接针对true
或false
进行测试是很常见的,也是更正确的,只需使用变量值的javascript truthy/false即可。
查看react router dom auth工作流示例。
这里需要注意的是,render
道具中的身份验证检查是。原因是当Router
被渲染时,私有路由将只被渲染一次,但匹配的路由将在必要时渲染/重新渲染其子路由。
- 尝试将身份验证检查移动到
render
道具中 - 添加一个加载状态并在身份验证检查挂起时返回null,使用
.finally
块发出未加载的信号 - 如果cookie存在或不存在,请保存一个布尔
isAuth
值
代码:
const PrivateRoute: FunctionComponent<AuthProps> = ({
component: Component,
path,
}: AuthProps) => {
return (
<Route
render={(routeProps) => {
const [isAuth, setIsAuth] = useState(false);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
axios
.get('http://localhost:5000/api/v1/checkcookie', {
withCredentials: true,
})
.then((response) => {
setIsAuth(!!response.data.cookie);
})
.finally(() => setLoading(false));
}, []);
if (loading) return null;
return isAuth ? <Component {...routeProps} /> : <Redirect to="/" />;
}}
/>
);
};