React-router:一旦安装,永远不要卸载路由上的组件,即使路由更改
Posted
技术标签:
【中文标题】React-router:一旦安装,永远不要卸载路由上的组件,即使路由更改【英文标题】:React-router: never unmount a component on a route once mounted, even if route change 【发布时间】:2018-02-05 14:43:06 【问题描述】:我有一个声明一些路由的 React 应用程序:
<Switch>
<Route exact path='/' render=this.renderRootRoute />
<Route exact path='/lostpassword' component=LostPassword />
<AuthenticatedRoute exact path='/profile' component=Profile session=session redirect='/' />
<AuthenticatedRoute path='/dashboard' component=Dashboard session=session redirect='/' />
<AuthenticatedRoute path='/meeting/:meetingId' component=MeetingContainer session=session redirect='/' />
<Route component=NotFound />
</Switch>
(AuthenticatedRoute
是一个检查会话的哑组件,要么调用<Route component=component />
要么<Redirect to=to />
,但最后调用component
方法)
基本上每个组件都在路由更改时安装/卸载。我想为Dashboard
路线保留这方面except,它做了很多事情,并且我想在不在仪表板上时卸载(假设您到达会议页面,您还不需要安装仪表板)但是一旦您加载了仪表板,当您进入个人资料页面、会议或其他任何内容时,当您返回仪表板时,组件就不必再次安装。
我在 React-router 文档上读到 render 或 children 可能是解决方案,而不是组件,但是我们可以将路由与子路由混合,而将其他路由与组件混合吗?我尝试了很多东西,但从未达到我想要的效果,即使使用render
或children
,我的仪表板组件仍在安装/卸载。
感谢您的帮助
【问题讨论】:
当路由在Switch
内时,只渲染第一个匹配的Route
,结果其他的被卸载。您应该将仪表板移出 Switch 并尝试..
@hazardous 嗨,你是对的!虽然需要一些调整,但它的工作原理!你想把它作为一个真正的答案发布,还是我应该用修改后的代码来回答自己?最佳
你为什么要打河?如果您的路线发生变化,任何不再属于您的 UI 的组件都会卸载。 这就是 React 的工作原理,以及它应该如何工作。因此,如果您需要数据独立于挂载状态而持久存在,只需......保持它在组件之外的持久性?您在 JS 领域,在您 require()
中的对象中维护您的仪表板状态在仪表板组件之外(以及因此缓存的引用),并让您的仪表板组件引导在componentWillMount
期间基于该数据。
@Mike'Pomax'Kamermans 我完全同意,这就是我通常所做的。但是关于我的仪表板:a)我有带有分页的 HOC 组件和有自己状态的东西,这将很难/脏地存储在仪表板状态 b)我有推送事件来实时为我的仪表板提供信息。我发现更容易(仅针对该页面)在安装后保持组件始终处于活动状态,让我减少糟糕的代码以在其外部保留复杂的状态和事件挂钩
@Mike'Pomax'Kamermans 我知道这是一个非常古老的评论,但这个建议充其量只是误导 - 我希望新手不要遵循它。组件可以有自己的状态是有原因的——因为一般来说,人们希望尽可能地保持状态本地化。为什么整个应用程序要知道某些组件的一些次要实现细节?至于与河流作战,这不是React 的工作方式,而是react-router 的工作方式,甚至不是(见接受的答案)。所以是的,保持组件安装是一种完全有效的技术,OP 询问如何做到这一点是正确的。
【参考方案1】:
Switch
组件只渲染一个路由,最早的匹配获胜。由于Dashboard
组件在其中,因此只要匹配到另一个路由,它就会被卸载。将这个Route
移到外面,它会与render
或children
一起正常工作。
【讨论】:
这是一个救命稻草的答案。但是有几件事。render
prop 对我不起作用。只有 children
道具有效。而您需要保持挂载的组件,您必须有条件地渲染内容,在其render()
函数中检查match
属性是否未定义。 link
示例代码沙箱:codesandbox.io/s/persist-state-react-router-1t4bl以上是关于React-router:一旦安装,永远不要卸载路由上的组件,即使路由更改的主要内容,如果未能解决你的问题,请参考以下文章