reactjs - 路由更改时停止重新渲染组件。尤其是 Routes 之外的组件

标签 reactjs react-router

我有以下组件结构:

  • 应用程序
  • 标题
  • 首页
  • 分类
  • 产品
  • 产品列表
  • 产品信息
  • 产品详情更多




  • 主要线路:

    <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/

    相关文章:

    reactjs - 在节点模块文件夹中编辑react npm模块的代码

    javascript - webpack 'import' 仅在顶层

    reactjs - ReactJS 中的登录页面与单页应用程序 (SPA) 分离

    reactjs - 如何在 React Native 中获取输入值?

    javascript - 如何以不同的颜色显示文本的某些部分,即@和}之间的数据应该是不同的颜色

    android - React Native- Android 中的准确阴影

    javascript - 自定义 Reactjs Checkbox 组件需要动态颜色

    javascript - React Router <LINK>如何在 Jest 测试中获取 href 的值

    javascript - React Router 链接重新加载页面 : Conflict with external event

    javascript - Gatsby-Redux : Component doesn't re-render on state changes