我有以下组件结构:
主要线路:
<div>
<Header />
<Switch>
<Route exact path="/" render={() => <Home />} />
<Route path="/category" render={() => <Categories />} />
<Route path="/products" render={() => <Products />} />
</Switch>
</div>
产品路线:
const productsData = [...];
return (
<div>
<div>
<ProductList data={productsData} />
</div>
<Switch>
<Route path={`${match.url}/:productId`} render={()=>
<ProductDetail data={productsData} />} />
<Route exact path={match.url} render={()=> (
<div style={{ textAlign: "center" }}>Select a product.</div>
)} />
</Switch>
</div>
);
ProductDetail中的路线:
return (
<>
<div>
<h3> {product.name} </h3>
Links:
<div>
<NavLink activeClassName="active" to={`${match.url}/detail/${ "100"}`}>
Click me
</NavLink>
</div>
</div>
<div>
<Route path={`${match.url}/detail/:code`} render={()=>
<ProductDetailMore />} />
</div>
</> );
当我点击“点击我”时,值 100 在我的 中正确显示产品详情更多组件,但所有组件都重新渲染(Products、ProductList、ProductDetail、ProductDetailMore);所以,我的问题是,如何防止在父组件 [Products, ProductDetail] 中重新渲染?
特别是,我想避免在 ProductList 中重新渲染,它不在 Route 中?
最佳答案
您通常不能真正避免重新渲染,因为 react 已经决定了哪些组件需要重新渲染。但是,这仅意味着您无法避免重新渲染父组件。使用 react 开发工具,您可以分析它们重新渲染的原因(这是分析器中的一个选项),并可能找到不必要的重新渲染原因。
但这些是好消息:
您可以轻松做的是防止子组件重新呈现。例如“产品列表”。一种方法是直接在组件的导出或“类别”组件中使用 React.memo HOC(在静态位置,而不是在渲染函数中):
const ProductListMemo = React.memo(ProductList)
然后,您在渲染函数中使用“ProductListMemo”。这样,当组件被渲染时,React 会预先检查是否有任何 props 发生变化。如果不是,则不会重新渲染组件。您的代码在某种程度上是不完整的。你定义const productsData = [...]
如果这是在渲染函数中,将始终创建一个新数组,即使内容相同,React.memo 也会看到一个新数组并重新渲染组件。您必须将数组移到渲染函数之外,或者必须将其包装在 useMemo 中(如果您不使用类组件):const productsData = useMemo(() => [...], []);
这个“useMemo”钩子(Hook)也可以用来避免组件的重新渲染,你可以使用{useMemo(() => (<div>
<ProductList data={productsData} />
</div>), [productsData])}
这样,每次重新渲染都会检查“productsData”是否更改,然后才重新渲染组件。所以要知道的重要一点是,如果父组件由于状态更新而重新渲染,它将重新渲染每个子组件。这些也将重新渲染它们的每个子组件。但是,使用 React.memo 或 useMemo,您可以帮助使用react以决定使用之前渲染的组件。
关于reactjs - 路由更改时停止重新渲染组件。尤其是 Routes 之外的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63284345/