强制React-Router <Link>加载页面,即使我们已经在该页面上

Mik*_*ans 17 react-router

有没有办法强制React-Router <Link>从路径加载页面,即使当前位置已经是该页面?我似乎无法在react-router文档中找到任何提及.

我们在"申请"路线上有一个页面,用于加载带有英雄形象,一些解释性文本等的着陆页,以及一个"申请此程序"按钮,该按钮交换作为申请表格的内容.这一切都发生在相同的"应用"路线上,因为如果没有首先点击着陆页,用户就无法直接导航到此表单.

但是,当他们打开这个表单时,他们再次单击导航菜单中的apply链接,整个页面应该像第一次安装时一样重新加载,让他们再次"返回"(但实际上,向前)到目标网页.

相反,单击" <Link>不执行任何操作",因为react-router看到我们已经在"apply"页面上,因此不会卸载当前页面然后安装另一个页面.

有没有办法强制它卸载当前页面然后挂载请求的页面,即使它是页面用户应该已经打开?(<Link>例如通过一个属性?)

小智 29

基于Link 组件的“react-router”v6官方文档

A 是一个允许用户通过单击或点击导航到另一个页面的元素。在react-router-dom中,a使用指向其链接到的资源的真实href来呈现可访问的元素。这意味着右键单击某个内容之类的操作可以按照您的预期进行。您可以使用 跳过客户端路由并让浏览器正常处理转换(就好像它是一个 )。

这样你就可以传递reloadDocument给你的<Link/>组件,它将始终刷新页面。

例子

<Link reloadDocument to={linkTo}> myapp.com </Link>

至少对我有用!


Pei*_* Li 14

在Route组件中,指定随机密钥.

<Route path={YOURPATH} render={(props) => <YourComp {...props} keyProp={someValue} key={randomGen()}/>} />
Run Code Online (Sandbox Code Playgroud)

当反应看到不同的键时,它们将触发重新渲染.

  • 虽然我喜欢这背后的想法,但您的答案还远未完成,并且仍然需要解释如何以实际触发重新渲染的方式触发对该键的更改。 (3认同)
  • 我使用 `Math.random` 来生成密钥。基本上发生的事情是,当您单击链接时,反应路由器评估您的箭头函数以获取组件,并通过每次使用随机传递一个新密钥来确保每次链接单击都被视为反应将重新渲染的道具更改。 (2认同)
  • 你的解决方案给了我不变的违规:超出最大更新深度。我认为这对于复杂的组件来说不是一个好主意 (2认同)
  • 这种方法看起来很老套 (2认同)

unl*_*.it 8

不是一个好的解决方案,因为它强制完整页面刷新并抛出错误,但您可以使用onClick处理程序调用forceUpdate(),如:

<Link onClick={this.forceUpdate} to={'/the-page'}>
    Click Me
</Link>
Run Code Online (Sandbox Code Playgroud)

我只能说是有效的.我自己也陷入了类似的问题,希望别人有更好的答案!

React router Link不会导致组件在嵌套路由中更新


Men*_*des 8

简单如:

<Route path="/my/path" render={(props) => <MyComp {...props} key={Date.now()}/>} />
Run Code Online (Sandbox Code Playgroud)

对我来说很好用。定位到相同路径时:

this.props.history.push("/my/path");
Run Code Online (Sandbox Code Playgroud)

页面会重新加载,即使我已经在/my/path.


fla*_*ash 6

我用来解决这一问题的一个解决方法是将state属性传递给link这样<Link to={{pathname: "/page", state: "desiredState"}}>Page</Link>。然后,可以像下面这样在目标组件的(say <Page />)中检查它componentWillReceiveProps

componentWillReceiveProps(nextProps){
  if (nextProps.location.state === 'desiredState') {
    // do stuffs
  }
}
Run Code Online (Sandbox Code Playgroud)

这样可以避免重新加载整个页面。在这里链接到我的答案


小智 6

这可能是一个普遍的问题,我一直在寻找下一次在我的工具箱中使用的不错的解决方案。React-Router提供了一些机制来知道用户何时尝试访问任何页面,即使他们已经访问过该页面。

读取location.key哈希值是一种完美的方法,因为每次用户尝试在任何页面之间导航时,哈希值都会更改。

componentDidUpdate (prevProps) {
    if (prevProps.location.key !== this.props.location.key) {
        this.setState({
            isFormSubmitted: false,
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

设置新状态后,将调用render方法。在示例中,我将状态设置为默认值。

参考:位置对象永远不会发生突变,因此您可以在生命周期挂钩中使用它来确定何时进行导航

  • 当然,这里的一个缺点是,这需要有一个“componentDidUpdate”,在每个道具和状态更新上不断运行代码,即使这几乎永远不会成为此代码测试的更改。一个更有效的解决方案会很好。 (2认同)

Zac*_*lor 5

我通过将新路线推入历史记录,然后用当前路线(或您想要刷新的路线)替换该路线来解决这个问题。这将触发react-router“重新加载”路由,而无需刷新整个页面。

<Link onClick={this.reloadRoute()} to={'/route-to-refresh'}>
    Click Me
</Link>

let reloadRoute = () => {
    router.push({ pathname: '/empty' });
    router.replace({ pathname: '/route-to-refresh' });
}
Run Code Online (Sandbox Code Playgroud)

React 路由器的工作原理是使用浏览器历史记录进行导航,而无需重新加载整个页面。如果您将路由强制写入历史记录,反应路由器将检测到这一点并重新加载该路由。替换空路线非常重要,这样您的后退按钮在推入后就不会带您到空路线。

根据react-router,看起来react router库不支持这个功能,而且可能永远不会,所以你必须以一种hacky的方式强制刷新。