重定向至登录时的上一个路径-React Router v4



我正在使用react router v4,并试图实现一种功能,即无论用户点击哪条路由,他都会被带到登录页面,即如果他还没有登录。

但登录后,他被重定向到登录前试图访问的同一页面

我已经使用下面的代码为其中两条路线做到了这一点,但不确定这是否是完成的最佳方式

<Route path="/dashboard" render={(props) => (
auth ? 
(<MainDash props={this.props} />) 
: 
(<Redirect to="/login"/>)
)}
/>
<Route exact path="/customers" render={(props) => (
auth ? 
(<MainApp />) 
: 
(<Redirect to="/login"/>)
)}
/>
<Route exact path="/staff" render={(props) => (
auth ? 
(<MainApp />)
: 
(<Redirect to="/login"/>)
)}
/>
<Route path="/login" component={Login} />
<Route path="/logout" component={Login} />

现在,虽然这是正确的工作,我不想重复相同的代码一次又一次的所有不同的路线。那么有更好的方法吗?

现在,在注销后,它没有显示任何内容,我希望它显示登录页面。因此,我也添加了以下几行,以便在用户注销后立即显示登录页面。

<Route path="/login" component={Login} />
<Route path="/logout" component={Login} />

但还有一个问题->尽管注销后它确实显示了登录组件(仍然显示路由为"/logoout"),但它将我带回登录表单(这次的路由是"/login"),从这个路由登录将我带到仪表板。现在,为什么会发生这种情况?

非常感谢在这方面的一些帮助,因为我仍在学习反应路由器

根据此示例,您可以制作一个组件PrivateRoute来包装Route,并在需要auth的路由时使用它。

这是示例中的组件代码。

const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
fakeAuth.isAuthenticated ? 
(<Component {...props}/>) 
: 
(
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}
/>
)
)}
/>
)

以前的答案不够详细。

解决方案:

路由器

<BrowserRouter basename={BASE_NAME}>
<Switch>
{publicRouteList()}
<Route exact key="login" path="/login" component={Login} />
{getLoggedRouteList(state.logged)}
<Redirect key="redirect-login" to="/login" />
</Switch>
</BrowserRouter>

getLoggedRouteList

const getLoggedRouteList = (logged) => {
if (!logged) {
return (
<Route
key="wait-login"
render={props => {
return (
<Redirect
to={{
pathname: '/login',
state: { from: props.location },
}}
/>
);
}}
/>
);
}
const output = [];
output.push(
/* Here place route list that need logged */
);
return output;
}

登录组件

class Login extends React.Component {
login = async param => {
const { location } = this.props;
const { state } = location;
/* Here place request login api */
// go to state.from if set before
if (state && state.from) {
history.replace(state.from);
}
// else go to home
else {
history.replace('/');
}
}
}

您可以使用查询字符串来实现这一点。

将依赖项查询字符串添加到react应用程序中。

每当用户试图访问受保护的路径时,如果用户尚未登录,则必须重定向到登录屏幕。要做到这一点,你会做这样的事情。

history.push('/login');

但我们可以将前面的作为查询传递,如下所示。我们可以从react-router中使用useLocation走上一条路径

const lastLocation = useLocation();
history.push(`/login?redirectTo=${lastLocation}`);

现在,在成功登录后,我们可以获得在上一个路径中传递的查询字符串。如果前面的路径是null,我们可以设置一个默认路径。

const handleSuccessLogin = () => {
const location = useLocation();
const { redirectTo } = queryString.parse(location.search);
history.push(redirectTo == null ? "/apps" : redirectTo);
};

灵感来自https://ui.dev/react-router-v4-query-strings/

这就是我最终的做法:

<Switch>
{loggedIn ? null : <Route path='/protectedPath' render={(props) => {
const {pathname} = props.location
// if the user tries to access a protected location, but is NOT logged in
// remember the location the user was trying to access
this.lastLocation = pathname
// redirect to login page
return <Redirect to='/loginPath' />
}} />}
<Route exact path='/loginPath' render={(props) => {
return <Login {...props} lastLocation={this.lastLocation} />
}} />
</Switch>

然后,在我的Login-组件中,我检查lastLocation-属性是否设置为检查用户是否应该在登录后重定向。

这个解决方案唯一让我感到困扰的是,函数代码是在第一个路由的呈现方法中使用的。但由于它直接重定向,我希望这一点可以忽略。

最新更新