【问题标题】:react-router: How do I update the url without causing a navigation/reload?react-router:如何在不导致导航/重新加载的情况下更新 url?
【发布时间】:2019-11-27 19:42:26
【问题描述】:

使用 react 路由器,我已经完成了更新 url:

this.props.history.push({
            pathname: `/product/${this.props.product.id}`,
        });

但是,这会导致重新渲染/导航更改。有没有办法在不这样做的情况下更新网址?

我的用例是我有一个产品列表,当我点击一个产品列表时,我会显示一个模态并希望将 url 更新为 example.com/product/1 之类的内容,以便链接可共享。

【问题讨论】:

标签: javascript reactjs react-router


【解决方案1】:

replace 将覆盖 URL

this.props.history.replace({ pathname: `/product/${this.props.product.id}`})

【讨论】:

  • 这肯定仍然会导致路由器采取行动,然后出现一个空白屏幕(我猜它找不到路由)
  • 真的,替换应该只覆盖 URL
  • 我发现这行得通:window.history.replaceState(null, null, /product/${this.props.product.id});
  • react-router replace 的行为应该类似于 replaceState。我可以确认替换不会触发渲染,查看这个小演示jsbin.com/jinazirowa/edit?html,js,output
  • 只要路由器路径封装了新路径,这应该可以在不刷新/重新渲染的情况下工作。
【解决方案2】:

无法使用 React Router 找到解决方案,但能够使用浏览器的历史界面通过调用:

window.history.replaceState(null, "New Page Title", "/pathname/goes/here")

您可以了解更多关于.replaceStatehere的信息。

React Router 的 history.replace 并不总是有效

React Router 的 history.replace 方法可能会也可能不会触发重新渲染,具体取决于您应用的路由设置(例如,您有一个包罗万象的 /* 路由)。它不会根据定义阻止渲染。

【讨论】:

  • 请注意,如果稍后再次修改,此更改可能会绕过 React Router 对当前路径的了解。例如。如果你使用这种方法追加1个子路径,然后使用RR向上导航1级,它会在视觉上跳转2,因为RR仍然认为该位置没有附加的子路径。
  • 我遇到了与 OP 完全相同的问题,并使用他的方法解决了它。非常感谢! @MagnusBull 浏览器历史记录我只是使用window.history.pushState(stringify(currentParams), "");,这似乎可以解决问题,尽管我没有遇到你谈到的子路径问题
  • @usr28765526 我的意思是,如果你使用 React Router 来处理导航,那么使用浏览器 API replaceState 可以被认为是“黑客”并且 RR 不会知道路径已更改。如果你在 URL 被修改后尝试使用 React Router 的 location,它将在它知道的 URL 的版本上操作:更改前的那个。这可能是不可预测和令人困惑的。
【解决方案3】:

当你在一个 react 组件中时,propshistory,你可以使用它。

对于那些即使不在 React 组件中也正在寻找一种导航方式的人,即您无法获得 props.history,这是一种方法:

在渲染路由器的组件中:

// outside the component
export const browserRouterRef = React.createRef();

// on render
<BrowserRouter ref={browserRouterRef}>

然后您可以在任何地方导入browserRouterRef 并使用browserRouterRef.current.history 更改路由,即使您不在react 组件中。

【讨论】:

    【解决方案4】:

    我正在使用一种很好的方式来欺骗用户,即 URL 不会改变。

    为此,您只需要像这样设置您的路线。

    const Home = '/';
    const About = '/ ';
    const Contact = '/  ';
    

    注意空格。所有字符都将计入引号内,因此它应该可以工作。

    Routes.tsx

    <Route exact path={Home} component={Home} />
    <Route exact path={About} component={About} />
    <Route exact path={Contact} component={Contact} />
    

    在您的About.tsxContact.tsx 中:

      useEffect(() => {
        window.history.replaceState(null, '', Home);
      }, []);
    

    用户导航到AboutContact 页面后,将调用挂钩并运行回调函数内的代码。它会在组件渲染后移除空格。

    这应该是伪装隐藏 URL 的干净技巧?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-16
      • 2014-02-14
      • 2020-01-11
      • 2023-03-08
      相关资源
      最近更新 更多