react router - 登录后重定向

时间:2015-12-06 16:28:20

标签: react-router

请您帮助我理解我可以使用最新版反应路由器(v1.1.0)的重定向机制。我想重定向到let history = createBrowserHistory(); ,具体取决于用户登录的成功与否。 我试图做以下事情 首先使用。

创建历史
history.pushState(null, 'abc')

然后尝试使用

推送状态
transitionTo()

什么都没发生。你可以告诉我正确的转换方式。从我理解的文档中,Log.getStackTraceString(exception) API在最新版本中不存在。 如果您能指出一个简单的工作示例,那将会很棒。

提前致谢。

8 个答案:

答案 0 :(得分:24)

想要更新这个帖子,因为我花了很多时间在这上面挖掘。在React Router 2.0.x中,不推荐使用replaceState以支持replace。有关详细信息,请参阅此处: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 :(得分:17)

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

路由上还有example of requiring auth,如果用户未登录,则会重定向到其他路径。

以下是app.js中来自require auth示例的摘录:

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的方法中。

答案 2 :(得分:9)

@terranmoccasin的回答是正确的。然而,通常需要很少的例子来解决。

我们假设您需要保护多条路线(仪表板1,仪表板2,......)。成功登录后,如何重定向回原始页面?换句话说,你如何处理{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月)与萝卜一起推出,创建了一个HOC。但是它包装了React.createClass,而不是JS类。我还没有能够使用redux-form等工作。此外我认为上面的代码更容易理解。

答案 3 :(得分:3)

  

React Router v4.2

我正在使用 React-16.2 &amp; React-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 :(得分:3)

我只想分享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)的详细信息

答案 5 :(得分:1)

onEnter 不再存在于 react-router-4,您可以利用 <Route render={ ... } /> 来实现相同的功能。

这是一个相同的例子。

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

isAuth() 在我的例子中是一个函数,它基本上检查我们是否有身份验证令牌,并根据它返回真/假。

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

答案 6 :(得分:1)

这对我有帮助。

Redirect to Login After Logout

  1. import { useHistory } from "react-router-dom";
  2. const history = useHistory();
  3. history.push("/login");

答案 7 :(得分:0)

@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(...)
  }
})

基本上:

  1. 定义contextType
  2. 使用this.context.router.push(...)
  3. 干杯。