react-router:如何在不导致导航/重新加载的情况下更新 url?

IT技术 javascript reactjs react-router
2021-04-05 20:27:04

使用react-router我已经完成了更新网址:

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

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

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

4个回答

无法使用 React Router 找到解决方案,但可以通过调用浏览器的历史记录界面来完成此操作:

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

您可以.replaceState 在此处了解更多信息

React Routerhistory.replace并不总是有效

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

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

替换将覆盖 URL

this.props.history.replace({ pathname: `/product/${this.props.product.id}`})
只要路由器路径封装了新路径,这应该可以在不刷新/重新渲染的情况下工作。
2021-05-26 20:27:04
真的,replace 应该只覆盖 URL
2021-06-04 20:27:04
那肯定仍然会导致路由器采取行动,然后出现一个空白屏幕(我猜它找不到路线)
2021-06-06 20:27:04
react-router replace 的行为应该像 replaceState。我可以确认替换不会触发渲染,检查这个小演示jsbin.com/jinazirowa/edit?html,js,output
2021-06-11 20:27:04
我发现这有效: window.history.replaceState(null, null, /product/${this.props.product.id});
2021-06-19 20:27:04

我正在使用一种很好的方式来欺骗用户,即 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.tsx里面Contact.tsx

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

用户导航到AboutContact页面后,将调用钩子并运行回调函数内的代码。它将在组件呈现后删除空格。

这应该是伪装隐藏网址的绝招😂

当你在react组件中时,propshas history,你可以使用它。

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

在渲染路由器的组件中:

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

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

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