reactjs - React - 如何在钩子useEffect中使用重定向?
问题描述
我正在尝试将未登录到我的应用程序的用户重定向到登录页面,并且我的路由文件中的 useEffect 中有一些条件,但是当我输入其中一个时,重定向不起作用并且我想知道它是否与 react-router-dom 有关
Route.js 文件代码如下:
import React, { useEffect } from 'react'; // nao estava
import { PropTypes } from 'prop-types';
import { Route, Redirect, useHistory } from 'react-router-dom';
import AuthLayout from '../pages/_layouts/auth';
import DefaultLayout from '../pages/_layouts/default';
import { store } from '../store';
export default function RouteWrapper({
component: Component,
isPrivate,
...rest
}) {
const { signed } = store.getState().auth;
const { googleSigned } = store.getState().googleAuth;
const history = useHistory();
useEffect(() => {
if (!signed && !googleSigned && isPrivate) {
return <Redirect to="/" />;
}
if ((signed && !isPrivate) || (googleSigned && !isPrivate)) {
return <Redirect to="/dashboard" />;
}
return <Redirect to="#" />;
}, [googleSigned, signed]);
const Layout =
signed || googleSigned || window.location.pathname === '/dashboard'
? DefaultLayout
: AuthLayout;
return (
<Route
{...rest}
render={(props) => (
<Layout>
<Component {...props} />
</Layout>
)}
/>
);
}
RouteWrapper.propTypes = {
isPrivate: PropTypes.bool,
component: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
.isRequired,
};
RouteWrapper.defaultProps = {
isPrivate: false,
};
signed 和 googleSigned 是 reducer 中存在的状态,重点是 google 签名,因为尚未实现使用普通登录获得的签名,而 google 签名是在应用程序后端使用 oAuth 实现的
此时我的应用程序的流程如下,用户单击 google 上的登录按钮被重定向到 google 身份验证屏幕,如果用户在应用程序中注册,他将被重定向到仪表板页面,仪表板页面并发送一个动作检查用户是否登录到应用程序,目的是如果用户未登录(googleSigned = false),他将被重定向回登录页面
解决方案
您的实施存在一些问题。首先也是最重要的,回报useEffect
并不像您希望的那样起作用。返回useEffect
实际上用于清除副作用,例如滚动侦听器或您不想在组件卸载后保留的类似内容。您可以在此处阅读更多相关信息:https ://reactjs.org/docs/hooks-effect.html 。
相反,您要做的是以编程方式重定向用户,而不是返回重定向组件。react-router-dom
你可以使用钩子useHistory
(https://reactrouter.com/web/api/Hooks/usehistory)来做到这一点。因此,我们可以利用历史记录来代替在您的钩子中返回<Redirect />
组件。useEffect
useEffect(() => {
if (!signed && !googleSigned && isPrivate) {
history.push("/");
}
if ((signed && !isPrivate) || (googleSigned && !isPrivate)) {
history.push("/dashboard");
}
history.push("#");
}, [googleSigned, signed]);
像上面这样的东西应该更接近你想要实现的目标。
推荐阅读
- html - 修复背景并将面板放在它上面
- cordova - 科尔多瓦相机插件错误 java.lang.NumberFormatException
- c# - EF Core 按相关 ID 查询数据
- c# - C# wpf,部分 ListView 绑定
- python - 从python中的项目导入时找不到模块
- jackson - Jackson InvalidFormatException:无法从字符串反序列化“java.util.UUID”类型的值
- react-native - 文字无故下线
- php - PHP将数组组织成产品细节
- postgresql - Gitlab Runner 中的 Docker 执行器通过 Symfony 的 Doctrine 将数据库解析为 localhost 而不是别名
- c# - HTTP 标头 Xamarin iOS