开发者问题收集

在 React Router 中将参数传递给路由

2017-03-30
5385

我定义了一条除非用户登录否则无法访问的路由。其代码如下:

    const App = ({ userLoggedIn }) => {
return (
        <Router>
          <div className="App">
            <Header userLoggedIn={ userLoggedIn }/>
            <ProtectedRoute path='/content' component={ Day } userLoggedIn={ userLoggedIn } />
            <Footer />
          </div>
        </Router>
      );
    }

我将 userLoggedIn 作为参数传递,因为应用程序会保留其状态。我以与 React Router 文档中的 Auth 示例类似的方式定义 ProtectedRoute。

const ProtectedRoute = ({ userLoggedIn, component, ...rest }) => (
  <Route {...rest} render={ props => (
    userLoggedIn ? (
      React.createElement(component, props)
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

但 userLoggedIn 始终为 null(即使在调用 ProtectedRoute 之前该值不为 null)。


我创建了一个更简单的示例,并在应用程序中进行了测试。我添加了以下行:

<TestRoute path='/test' userLoggedIn={ userLoggedIn }/>

并创建了 TestRoute 组件,如下所示:

    const TestRoute = ({ userLoggedIn }) => {
  console.log(userLoggedIn);
  return (
    <Redirect to={{
      pathname: userLoggedIn ? '/yes' : '/no'
    }}/>
  )
}

我现在看到的是控制台中出现了两次 null ,然后是 userLoggedIn 的真实值...我猜组件第一次收到 null 时会重定向到 /no ,因此当真实值“到达”时,它不会像应该的那样转到 /yes ...


我如何访问我传递的 userLoggedIn 参数?有人有类似的例子吗?

谢谢

3个回答

好的,尝试了几种方法后,我发现了一种对我有用的方法,它比我尝试做的还要简单。

在应用程序部分,我有 Router ,我创建了一个使用条件编码的 Route

<Route path='/content' component={ userLoggedIn ? Day : LoginPage } />

这就是我所需要的。如果用户已登录,它将呈现 Day 组件,如果未登录,则重定向到 LoginPage 。也许这不是最好的解决方案,但对我来说很有效。

如果有人有更好的解决方案,请告诉我。

Alberto
2017-03-30

您可以通过 props.routeprops.route.userLoggedIn 访问路由器属性。

如果您的组件不是顶级组件,您可以将其包装在 withRouter 中或通过 v4 中的 context 访问它,但看起来您不需要这样做。

nanobar
2017-03-30

在用户访问页面之前,为了进行导航检查,请检查您的 userLoggedIn ,我使用 onEnter 方法。

<Route path='/content' onEnter={userLoggedIn} component={Day} />

因此,您的 userLoggedIn 可以像这样

function userLoggedIn(nextState, replace) {
  // check if your user is logged in
  if (localStorage.getItem('isLogged') !== 'true') {
    // block navigation and redirect to login page
    replace({ pathname: '/login', state: { nextPathname: nextState.location.pathname } });
    return true;
  }
  return false;
}

希望这对您有所帮助

ansmonjol
2017-10-16