Существует ли системный подход к отладке того, что вызывает повторную визуализацию компонента в React? Я поместил простой console.log (), чтобы увидеть, сколько раз он рендерится, но у меня возникают проблемы с выяснением того, что вызывает рендеринг компонента несколько раз, т.е. (4 раза) в моем случае. Существует ли инструмент, который отображает временную шкалу и / или все компоненты дерева отображает и порядок?
156
shouldComponentUpdate
чтобы отключить автоматическое обновление компонентов, а затем начать свою трассировку оттуда. Дополнительную информацию можно найти здесь: facebook.github.io/react/docs/optimizing-performance.htmlОтветы:
Если вы хотите короткий фрагмент без каких-либо внешних зависимостей, я считаю это полезным
Вот небольшой хук, который я использую для отслеживания обновлений компонентов функций
источник
setState
метод (в компоненте класса) с помощью,setState(...args) { super.setState(...args) }
а затем установить точку останова в вашем отладчике, которую вы затем сможете проследить до функции, устанавливающей состояние.useTraceUpdate
после того, как я определил это, как вы написали?function MyComponent(props) { useTraceUpdate(props); }
и он будет регистрировать всякий раз, когда изменяется реквизитthis.state
не определено.Вот несколько примеров того, как компонент React будет перерисован.
this.setState()
внутри компонента. Это вызовет следующие составные методы жизненного циклаshouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
props
. Этот триггер будетcomponentWillReceiveProps
>shouldComponentUpdate
>componentWillUpdate
>render
>componentDidUpdate
(connect
методreact-redux
триггера этого , когда есть изменения , применимые в магазине Redux)this.forceUpdate
который похож наthis.setState
Вы можете свести к минимуму повторное рендеринг вашего компонента, выполнив проверку внутри себя
shouldComponentUpdate
и вернув ее,false
если в этом нет необходимости.Другим способом является использование
React.PureComponent
компонентов без сохранения состояния. Чистые и не сохраняющие состояния компоненты повторно визуализируются только при наличии изменений в его реквизите.источник
shouldComponentUpdate
, либо расширятьReact.PureComponent
, чтобы обеспечить только повторный рендеринг при изменении.const MyComponent = (props) => <h1>Hello {props.name}</h1>;
(это компонент без состояния). Он будет перерисовываться всякий раз, когда родительский компонент перерисовывается.Ответ @ jpdelatorre хорош в освещении общих причин, по которым компонент React может перерисовываться.
Я просто хотел погрузиться немного глубже в один случай: когда реквизит меняется . Устранение неполадок, связанных с повторным рендерингом компонента React, является распространенной проблемой, и, по моему опыту, много раз отслеживание этой проблемы включает определение того, какие реквизиты меняются .
Реактивные компоненты пересчитывают каждый раз, когда получают новые реквизиты. Они могут получать новые реквизиты, такие как:
<MyComponent prop1={currentPosition} prop2={myVariable} />
или если
MyComponent
подключен к хранилищу резервов:В любое время значение
prop1
,prop2
,prop3
, илиprop4
измененияMyComponent
будут повторной визуализации. С 4 реквизитами не так сложно отследить, какие реквизиты меняются, поместивconsole.log(this.props)
в этом началеrender
блока. Однако с более сложными компонентами и все большим количеством реквизита этот метод несостоятельный.Вот полезный подход ( для удобства использующий lodash ), чтобы определить, какие изменения реквизита вызывают повторный рендеринг компонента:
Добавление этого фрагмента к вашему компоненту может помочь выявить виновника сомнительного повторного рендеринга, и много раз это помогает пролить свет на ненужные данные, передаваемые по компонентам.
источник
UNSAFE_componentWillReceiveProps(nextProps)
и не рекомендуется. «Этот жизненный цикл был ранее названcomponentWillReceiveProps
. Это имя будет работать до версии 17». Из документации React .Странно, никто не дал такого ответа, но я считаю его очень полезным, тем более что изменения в подпорках почти всегда глубоко вложены.
Крючки фанатов:
"Старые" школьные фанаты:
PS Я все еще предпочитаю использовать HOC (компонент более высокого порядка), потому что иногда вы деструктурируете свои реквизиты сверху, и решение Джейкоба не подходит
Отказ от ответственности: Нет связи с владельцем пакета. Простое нажатие в десятки раз, чтобы попытаться обнаружить разницу в глубоко вложенных объектах, - это боль в.
источник
Теперь есть доступ к этому на npm:
https://www.npmjs.com/package/use-trace-update
(Раскрытие, я опубликовал его) Обновление: Разработано на основе кода Джейкоба Раска
источник
Использование хуков и функциональных компонентов, а не только изменение реквизита, может вызвать повторное рендеринг. Я начал использовать довольно ручной журнал. Я очень помог мне. Вы также можете найти это полезным.
Я вставляю эту часть в файл компонента:
В начале метода я держу ссылку на WeakMap:
Затем после каждого «подозрительного» звонка (реквизит, хук) пишу:
источник
Приведенные выше ответы очень полезны, на тот случай, если кто-то ищет конкретный метод для обнаружения причины повторного рендеринга, тогда я нашел эту библиотеку redux-logger очень полезной.
Что вы можете сделать, это добавить библиотеку и включить различие между состояниями (оно есть в документации), например:
И добавьте промежуточное программное обеспечение в магазине.
Затем поместите
console.log()
в функцию рендеринга компонента, который вы хотите проверить.Затем вы можете запустить свое приложение и проверить наличие консольных журналов. Где бы ни находился журнал непосредственно перед тем, как он покажет вам разницу между состоянием,
(nextProps and this.props)
вы можете решить, действительно ли необходим рендеринг.Это будет похоже на изображение выше вместе с ключом diff.
источник