有没有一种干净的方法可以有条件地为同一个 React Router 路由加载和渲染不同的组件?

Is there a clean way to conditionally load and render different components for the same React Router route?

用例是我想根据用户是否登录将根 (/) 映射到两个不同的组件之一,我希望这两个组件驻留在不同的包中并延迟加载, 所以简单地将登录检查放在 render() 方法中是不行的。

我尝试使用带有 require.ensure() 的动态路由定义来延迟加载组件,这是第一次工作,但是在更改登录状态后组件没有更新(即使我导航到另一条路线并返回 / )。 我试图通过在包含路由器的组件上设置 props 来强制重新渲染路由器,手动方式和将其设置为 Redux 连接组件,我还尝试向 Redux 存储添加一个侦听器并更改组件状态作为响应登录更改,但在所有尝试中我都收到错误 "You cannot change ; it will be ignored" 并且组件没有更改。

我丑陋的解决方案是在路由器外部加载不同的组件代码,监听登录状态变化并作为响应加载匹配组件并将其设置为包装组件的状态,该状态在渲染中引用( ) 代码。有没有一种干净的 "React-Router-ish" 方法来做我想做的事?

最接近干净的“React-Router-ish”方式的方法是使用 React Router Enterhooks

enter 挂钩是一个用户定义的函数,在将要呈现路线时调用。它接收下一个路由器状态作为它的第一个参数。替换函数可用于触发到不同 URL.

的转换

因此,请在 <Route /> 上使用 onEnter(nextState, replace, callback?) 属性。

Called when a route is about to be entered. It provides the next router state and a function to redirect to another path. this will be the route instance that triggered the hook.

If callback is listed as a 3rd argument, this hook will run asynchronously, and the transition will block until callback is called.

我遵循的一般最佳做法是将身份验证检查流程放在远离您的路线的地方,并将其放在过渡 events/hooks.[=17= 内]

通常的行为是 - 在实际呈现路由处理程序之前,检查身份验证,并将用户重定向到另一条路由。在你的情况下,如果你想使用相同的路线,但渲染不同的组件 - 你也应该能够使用相同的技术来做到这一点。然而,这不是一件常见的事情(根据我所看到的),但它应该是可能的。

有关此方法的完整示例,here's the auth-flow code example you can check。它是由 React Router 的创建者共享的,因此对我来说它看起来很可信。

PS:我的回答对 React Router 版本 > 0.13.x.

有效

React Router 4 几乎解决了这个问题,因为它将路由配置作为组件渲染的一部分,因此无论是基于位置还是基于其他条件渲染都是一样的props/state.