Остановить повторную отрисовку компонентов при изменении маршрута. Особенно компоненты вне маршрутов - PullRequest
2 голосов
/ 06 августа 2020

У меня следующая структура компонентов:

  • Приложение
    • Заголовок
    • Дом
    • Категории
    • Продукты
      • Список продуктов
      • Сведения о продукте
        • Подробнее

Главная Маршрут:

<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 правильно отображается в моем ProductDetailMore компоненте, но все компоненты повторно обработанный (Products, ProductList, ProductDetail, ProductDetailMore); Итак, мой вопрос: как я могу предотвратить повторный рендеринг в родительских компонентах [Products, ProductDetail]?

И особенно я хотел бы избежать повторного рендеринга в ProductList, который не в маршруте?

1 Ответ

1 голос
/ 06 августа 2020

Как правило, вы не можете избежать повторного рендеринга, поскольку react уже решает, какие компоненты нуждаются в повторном рендеринге. Однако это означает только то, что вы не можете избежать повторного рендеринга родительских компонентов. С помощью инструментов React Dev вы можете проанализировать, почему они повторно рендерится (это опция в профилировщике) и, возможно, найти ненужные причины для повторных рендеров.

Но это хорошие новости:

Что вы можете легко do предотвращает повторную визуализацию подкомпонентов. Например, «ProductList». Один из способов - это React.memo HO C, используемый непосредственно при экспорте компонента или в компоненте «Категории» (в местоположении stati c, а не в функции рендеринга):

const ProductListMemo = React.memo(ProductList)

Затем вы используете "ProductListMemo" в функции рендеринга. Таким образом, когда компонент отображается, React заранее проверяет, изменились ли какие-либо свойства. В противном случае компонент не визуализируется повторно. Однако ваш код как-то неполный. Вы определяете

const productsData = [...]

. Если это находится в функции рендеринга, всегда будет создаваться новый массив, и даже если содержимое останется таким же, React.memo увидит новый массив и повторно отрендерит компонент. Вы должны переместить массив за пределы функции рендеринга или вы должны обернуть его в useMemo (если вы не используете компоненты класса):

const productsData = useMemo(() => [...], []);

Этот хук «useMemo» также можно использовать для избегайте повторной визуализации компонентов, вы можете использовать

{useMemo(() => (<div>
    <ProductList data={productsData} />
</div>), [productsData])}

Таким образом, каждая реакция на повторную визуализацию проверяет, изменились ли "productsData", и только затем повторно визуализирует компоненты.

Поэтому важно знать что если родительский компонент выполняет повторную визуализацию, например, из-за обновления состояния, он будет повторно отображать каждый дочерний компонент. И они также будут перерисовывать каждый из своих дочерних компонентов. Однако с помощью React.memo или useMemo вы можете помочь отреагировать и принять решение использовать вместо этого ранее визуализированный компонент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...