как предотвратить повторный рендеринг дочернего компонента при изменении родительского компонента состояния/реквизита?

прямо сейчас у меня есть компонент дерева, подобный этому

<UserOrderApproval>
  <Table>
    <TableRow> 
      <ComponentList />
    </ChildrenProps1>
  </Parent>
</UserOrderApproval>    

я беру реквизиты из избыточности в компоненте UserOrderApproval и передаю эти реквизиты каждому дочернему компоненту. Проблема заключается в том, что когда дочерний компонент вносит некоторые изменения в избыточность, состояние компонента UserOrderApproval изменится и заставит все дочерние компоненты перерисовать и снова запустить жизненный цикл компонента. Как это предотвратить?

Как лучше всего передавать реквизиты от родителя к вложенным дочерним элементам?

Огромное спасибо


person Endy Santoso    schedule 17.12.2018    source источник
comment
shouldComponentUpdate() ? Подробнее: reactjs.org/docs/react-component.html#shouldcomponentupdate   -  person iRohitBhatia    schedule 17.12.2018


Ответы (3)


Как сказал KuchBhi, вам нужно будет использовать метод shouldComponentUpdate жизненного цикла.

shouldComponentUpdate вызывается в любое время, когда новые свойства или состояние передаются компоненту, и по умолчанию возвращает true (может возвращать true только для обновленных свойств, но не на 100%). Метод принимает два параметра: nextProps и nextState. Затем вы можете сравнить их с this.props и this.state, чтобы решить, следует ли вам обновлять или нет.

Стандартная/типичная реализация этого метода выглядит примерно так (псевдо):

shouldComponentUpdate(nextProps, nextState) {
  //Really it's a deeper equality check, not just the props/state object
  return this.props !== nextProps || this.state !== nextState;
}

Что вы можете сделать в качестве альтернативы, так это немного расширить это со случаями, когда возвращается false. Вот пример из одного из моих проектов, где я хочу перерендерить только два конкретных реквизита:

shouldComponentUpdate(nextProps) {
  const minUpdated = this.props.min !== nextProps.min;
  const maxUpdated = this.props.max !== nextProps.max;
  return minUpdated || maxUpdated;
}

Компонент также имеет реквизиты, такие как масштаб, выравнивание, ширина и т. д., но я не хочу обновлять их, когда получаю новые реквизиты, поэтому я не проверяю, не равны ли они.

По сути, вы можете просто вернуть false в этом методе и никогда не обновлять после начальной загрузки, но я бы избегал этого, поскольку это противоречит цели реагирования.

редактировать: как сказал varoons, это, вероятно, отличный сценарий для вас, чтобы использовать новый API контекста, и я настоятельно рекомендую изучить его, но также полезно знать о методах жизненного цикла компонентов.

person Ryan - Llaver    schedule 17.12.2018

Используйте shouldComponentUpdate(), чистые компоненты или подключайте избыточность только к тем дочерним компонентам, которые в них нуждаются.

https://reactjs.org/docs/react-component.html#shouldcomponentupdate

https://reactjs.org/docs/react-api.html#reactpurecomponent

person CodeDraken    schedule 17.12.2018
comment
shouldComponentUpdate только для корневого компонента или дочерних? кто лучше передает метод для изменения состояния / реквизита от родителя, или у детей есть собственный метод для этого? Спасибо - person Endy Santoso; 18.12.2018

Это хороший сценарий для использования контекстного API React, так как это похоже на случай сверления реквизита — вы передаете данные компонентам, которые их не используют. Вы можете сделать UserOrderApproval (при условии, что это родитель, подключенный к глобальному состоянию/редукции) поставщиком контекста, а ComponentList - потребителем. Таким образом, будут повторно отображаться только компоненты, обрабатывающие/использующие данные.

https://reactjs.org/docs/context.html

https://scotch.io/tutorials/get-to-know-reacts-new-context-api

person varoons    schedule 17.12.2018