反应路由器 - 登录后重定向

Posted

技术标签:

【中文标题】反应路由器 - 登录后重定向【英文标题】:react router - Redirection after login 【发布时间】:2016-03-11 05:49:12 【问题描述】:

能否请您帮助我了解最新版本的 react router (v1.1.0) 可以使用的重定向机制。我想根据 user login 的成功或失败重定向到 url。 我试图做以下事情 首先使用创建历史记录。

let history = createBrowserHistory();

然后尝试使用

推送状态
history.pushState(null, 'abc')

什么都没有发生。您能否让我知道进行转换的正确方法。从文档中我了解到transitionTo() API 在最新版本中不存在。 如果您能指出一个简单的工作示例,那就太好了。

提前致谢。

【问题讨论】:

Automatic redirect after login with react-router的可能重复 简单方式***.com/a/53916596/3966458 【参考方案1】:

想更新这个帖子,因为我花了很多时间研究这个问题。在 React Router 2.0.x 中,replaceState 已弃用,取而代之的是替换。详情见这里:https://github.com/ReactTraining/react-router/blob/v2.0.0/upgrade-guides/v2.0.0.md#link-to-onenter-and-isactive-use-location-descriptors

正确的做法是这样的:

function requireAuth(nextState, replace) 
  if (!userExists()) 
    replace(
      pathname: '/signin',
      state:  nextPathname: nextState.location.pathname 
    )
  


export const renderRoutes = () => (
  <Router history=browserHistory>
      <Route path="protectedRoute" component=Protected onEnter=requireAuth />
      <Route path="signin" component=SignIn />
    </Route>
  </Router>
);

然后,在 SignIn 组件中,您可以在成功登录后重定向,如下所示:

signInFunction(params, (err, res) => 
  // Now in the sign in callback
  if (err)
    alert("Please try again")
  else 
    const location = this.props.location
    if (location.state && location.state.nextPathname) 
      browserHistory.push(location.state.nextPathname)
     else 
      browserHistory.push('/')
    
  
)

【讨论】:

这是比接受的更好的答案。 +1 登录功能。 这些 React 存储库不断迁移! github.com/ReactTraining/react-router/blob/v2.0.0/… onEnter 在 react-router-4 上不再存在。您应该使用 来获得所需的功能。 reacttraining.com/react-router/web/api/Redirect【参考方案2】:

您可以在您进入和离开路线时触发的路线上注册“挂钩”。查看onEnter and onLeave hooks 的文档。

路由上还有一个example of requiring auth,如果用户未登录,则重定向到不同的路径。

这是从 app.js 中的 require auth 示例中提取的 sn-p:

function requireAuth(nextState, replaceState) 
  if (!auth.loggedIn())
    replaceState( nextPathname: nextState.location.pathname , '/login')


// And from the route configuration, use the requireAuth function in onEnter...
<Router history=history>
  <Route path="/" component=App>
    <Route path="login" component=Login />
    <Route path="logout" component=Logout />
    <Route path="about" component=About />
    <Route path="dashboard" component=Dashboard onEnter=requireAuth />
  </Route>
</Router>

nextStatereplaceState 参数是来自 rackt/history 的对象,并被注入到您传递给 onEnter 的方法中。

【讨论】:

谢谢。再问一次。反应路由器中的 是否等同于角度视图? 考虑到最近在React Hooks 周围的嗡嗡声,可能会考虑在您的回复中使用新术语。【参考方案3】:

React 路由器 v4.2

我正在使用 React-16.2React-router-4.2

我由此得到解决方案 this.props.history.push("/");

我的工作代码:

    .then(response => response.json())
        .then(data => 
            if(data.status == 200)
                this.props.history.push("/");
                console.log('Successfully Login');
          
        )

我在关注这个文档redirect-on-login-and-logout

【讨论】:

像魅力一样工作 虽然路径得到更新但没有加载“/”路径,但我无法正常工作【参考方案4】:

@terranmoccasin 的回答是正确的。然而有一个共同的需要很少的例子地址。

假设您需要保护多条路线(dashboard1、dashboard2、...)。登录成功后如何重定向回原来的页面?换句话说,你用nextPathname: nextState.location.pathname做什么?

这是我在./containers/LoginContainer.js 中所做的:

import  push  from 'react-router-redux';
const mapStateToProps = (state) => (
  nextPathname: state.routing.locationBeforeTransitions.state.nextPathname,
);
const mapDispatchToProps = (dispatch) => (
  changeLocationOnSignIn: (nextPathname) => 
    dispatch(push(nextPathname));
  ,
);

./components/Login.js

componentWillReceiveProps(nextProps) 
  // user signed in or signed up, assuming redux. you may use this elsewhere.
  if (nextProps.user.status === 'authenticated' && nextProps.user.user &&
     !nextProps.user.error) 
       this.props.changeLocationOnSignIn(this.props.nextPathname);
  

React-router 2.4.0(2016 年 4 月)引入了 withRouter,它创建了一个 HOC。但是它包装了 React.createClass,而不是 JS 类。我无法让它与 redux-form 等一起使用。此外,我认为上面的代码更容易理解。

【讨论】:

关于@justabuzz,我应该提到我正在使用 Redux,我希望使用 Redux 记录重定向。否则 push() 就可以了。【参考方案5】:

我只想分享 2020 年的实际答案。 在状态中存储先前位置的主要方式是相同的。但是 onEnter 已从库中删除。现在我们可以像documentation一样使用AuthRoute:

<AuthRoute exact path="/food">
  <Food />
</AuthRoute>
<Route exact path="/login">
  <Login />
</Route>
const AuthRoute = ( children, isAuthorized, ...rest ) => 
  const loginLink = usePrepareLink(
    to: "/login",
    isRelativePath: true
  );

  return (
    <Route ...rest render=( location ) =>
      isAuthorized ? (
        children
      ) : (
        <Redirect to=
          ...loginLink,
          state:  from: location 
         />
      )
     />
  );
;

我们可以在登录后使用状态恢复以前的URL

const onSignIn = useCallback(() => 
  setIsAuthorized(value);
  const link = (state && state.from) || "/restore-prevented-route";
  history.replace(link);
, [setIsAuthorized, value, history, state]);

您可以找到here(或RU)的详细信息

【讨论】:

【参考方案6】:

这对我有帮助。

Redirect to Login After Logout

    import useHistory from "react-router-dom"; const history = useHistory(); history.push("/login");

【讨论】:

【参考方案7】:

onEnter 不再存在于react-router-4 上,您可以使用&lt;Route render= ... /&gt; 来实现相同的功能。

这是一个相同的例子。

<React.Fragment>
    <Switch>
      <Route path="/dashboard" render=() => (isAuth() ? <Redirect to="/login" /> : <DashboardRoutes />) />
      <Route path="/login" component=Login />
    </Switch>
</React.Fragment>

isAuth() 在我的例子中是一个基本上检查我们是否有 auth 令牌并根据它返回 true/false 的函数。

function isLoggedIn() 
  if (!localStorage.getItem('token')) 
    return true;
  
  return false;

【讨论】:

【参考方案8】:

正如@JohnSz 提到的,我在使用 withRouter 时也遇到了问题。相反,我按照此处的说明进行操作: https://github.com/reactjs/react-router/blob/master/upgrade-guides/v2.0.0.md#programmatic-navigation

const RouteComponent = React.createClass(
  contextTypes: 
    router: React.PropTypes.object.isRequired
  ,
  someHandler() 
    this.context.router.push(...)
  
)

基本上:

    定义上下文类型 使用 this.context.router.push(...)

干杯。

【讨论】:

以上是关于反应路由器 - 登录后重定向的主要内容,如果未能解决你的问题,请参考以下文章

如何在您的登录 api 的 Json 响应后重定向用户反应本机

登录成功后重定向express js路由

Laravel 5.5登录后重定向到特定路由

Vue如何在登录后重定向用户到主要组件

在 React 中提交后重定向

laravel 5.2 登录后重定向到预期的网址