react-router:如何在不导致导航/重新加载的情况下更新 url?
Posted
技术标签:
【中文标题】react-router:如何在不导致导航/重新加载的情况下更新 url?【英文标题】:react-router: How do I update the url without causing a navigation/reload? 【发布时间】:2019-11-27 19:42:26 【问题描述】:使用 react 路由器,我已经完成了更新 url:
this.props.history.push(
pathname: `/product/$this.props.product.id`,
);
但是,这会导致重新渲染/导航更改。有没有办法在不这样做的情况下更新网址?
我的用例是我有一个产品列表,当我点击一个产品列表时,我会显示一个模态并希望将 url 更新为 example.com/product/1 之类的内容,以便链接可共享。
【问题讨论】:
这都是 react-router 内置的;它被称为dynamic routing 【参考方案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")
您可以了解更多关于.replaceState
here的信息。
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 组件中时,props
有 history
,你可以使用它。
对于那些即使不在 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.tsx
和Contact.tsx
中:
useEffect(() =>
window.history.replaceState(null, '', Home);
, []);
用户导航到About
或Contact
页面后,将调用挂钩并运行回调函数内的代码。它会在组件渲染后移除空格。
这应该是伪装隐藏 URL 的干净技巧?
【讨论】:
以上是关于react-router:如何在不导致导航/重新加载的情况下更新 url?的主要内容,如果未能解决你的问题,请参考以下文章
带有 Reactstrap 的 React-Router 导致警告
React-Router & useContext,无限重定向或重新渲染