如何使用 react-router-dom 卸载路由更改上的组件而不是重新渲染 [重复]
Posted
技术标签:
【中文标题】如何使用 react-router-dom 卸载路由更改上的组件而不是重新渲染 [重复]【英文标题】:How to remount a componet on Route change using react-router-dom instead of re-rendering [duplicate] 【发布时间】:2019-11-14 07:17:51 【问题描述】:更新:这个问题与重复问题有何不同?
这里我们有相同的组件被 2 个不同的路由渲染。 在另一个问题中,OP 想知道如何重新安装一个被相同的路由一遍又一遍渲染的组件,只需更改路由参数即可。
链接:Component does not remount when route parameters change
我在ProductSearch
组件上有以下情况。
它可能被两个不同的<Route>'s
渲染:
它们都显示ProductSearch
页面,并带有相应产品的过滤器。
<Route exact path='/category/:slug' component=ProductSearchContainer/>
<Route exact path='/search/:slug' component=ProductSearchContainer/>
第一个发生在您点击产品类别菜单时:
因此结果已经在特定类别中。 然后它会显示特定于该产品类别的过滤器。第二个发生在您使用带有一些文本的 SearchBar
搜索产品时。
Price
、Brand
、Rating
等...
问题在于,如果您直接从一条路由更改为另一条,组件将简单地重新渲染。我希望它能够更好地重新安装,因为这样我就可以重新开始我选择的过滤器活动状态和产品列表等...
例如,这会发生在以下场景中:
-
用户点击分类导航按钮
Phones
ProductSearch
组件为 Phones
类别呈现
用户过滤了一堆东西并决定进行文本搜索并从头开始
用户搜索some random text
ProductSearch
被重新渲染(使用第二条路线)但如果我不重置所有过滤状态将保持不变。
注意下面 GIF 中的 URL 变化:
问题:
有没有办法确保我的组件在这种情况下更改为不同的路由时会重新安装?
CodeSandbox 示例:
https://codesandbox.io/s/react-routerremountonroutechangeso-881m3
完整代码:index.js
(如果 CodeSandbox 链接不再可用)
import React, useEffect from "react";
import ReactDOM from "react-dom";
import BrowserRouter as Router, Link, Switch, Route from "react-router-dom";
import "./styles.css";
function App()
return (
<Router>
<AllRoutes />
</Router>
);
function AllRoutes(props)
return (
<Switch>
<Route exact path="/" component=Home />
<Route exact path="/category/:slug" component=ProductSearch />
<Route exact path="/search/:slug" component=ProductSearch />
</Switch>
);
function Home(props)
return (
<div>
<div>I am Home</div>
<div>
<Link to="/category/phones">Phones</Link>
</div>
</div>
);
function ProductSearch(props)
console.log("Rendering ProductSearch...");
useEffect(() =>
console.log("ProductSearch mounted...");
return () => console.log("ProductSearch unmounted...");
, []);
// useEffect(() =>
// console.log('Inside useEffect for slug...');
// console.log(props.match.params.slug);
// ,[props.match.params.slug]);
return (
<div>
<div>I am ProductSearch</div>
<div>
<Link to="/">Home</Link>
</div>
<div>
<Link to="/search/phoneModelXYZ">Search for Phone XYZ</Link>
</div>
</div>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
【问题讨论】:
Component does not remount when route parameters change 的可能重复项 - 其中一个答案显示了一种强制重新安装的方法,其他答案解释了为什么最好不要这样做。 【参考方案1】:所以这就是我最终做的事情:
通过在 Route 中为渲染组件提供一个键,您可以使其重新挂载而不是重新渲染。
<Route exact path='/category/:slug' render=(routeProps)=>
<ProductSearch ...routeProps key=routeProps.match.params.slug/>
/>
<Route exact path='/search/:slug' render=(routeProps)=>
<ProductSearch ...routeProps key='search'/>
/>
现在我得到以下结果:
【讨论】:
以上是关于如何使用 react-router-dom 卸载路由更改上的组件而不是重新渲染 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
尝试导入错误:“Switch”未从“react-router-dom”导出
./src/App.js 尝试导入错误:“Switch”未从“react-router-dom”导出
使用 react-router-dom 时如何避免“功能组件不能被赋予 refs”?