Реагировать на оптимизацию рендеринга - PullRequest
3 голосов
/ 18 июня 2019

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

Как пример:

Я просто подключилсячтобы уменьшить компонент контейнера хранилища с помощью реквизита «items» (который является массивом).

const Component = ({ items }) => (
    <>{items.map(item => <ItemComponent key={item.id} {...item} />}</>
);

const mapStateToProps = state => ({
    items: $$data.select.items(state),
});

const ConnectedComponent = connect(mapStateToProps)(MyComponent);

Каждый раз, когда изменяется любая часть сложного хранилища - изменяется также и реквизит предметов, даже если данные предметов не обновлялись,даже если он пуст: oldProp: [] => newProp: [].И это вызывает рендеринг.(Я нашел его в React Dev Tools, он выделяет обновленные компоненты)

Стоит ли беспокоиться об этих ненужных повторных визуализациях?Как лучше всего с этим бороться?Я уже обнаружил, что новый React.memo hoc останавливает рендеринг, но разве это хорошо?

Ответы [ 5 ]

5 голосов
/ 18 июня 2019

Использование mapStateToProps в вашем вызове connect() означает, что вы хотите, чтобы ваш компонент был уведомлен об изменении магазина - это произойдет независимо от того, изменился небольшой интересующий вас фрагмент или нет. В дополнение к этому, react-redux предотвращает ненужную повторную визуализацию, выполняя поверхностное сравнение объекта, возвращенного mapStateToProps, и предыдущих операций.

Глядя на ваш пример, подобные сценарии newProp: []будет каждый раз создавать новый массив, поэтому не удастся выполнить поверхностное сравнение, поскольку массивы - это разные экземпляры.

Стоит ли беспокоиться об этом излишних повторных рендерингах?

React не заботитсяповторное рендеринг компонентов излишне, поэтому, даже если render вызывается снова, пока props к указанному компоненту фактически не изменился, React не будет выполнять никакой дополнительной работы.Вероятно, можно с уверенностью сказать, что для большинства приложений ненужные повторные рендеринг не так уж и серьезны.

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

4 голосов
/ 26 июня 2019

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

3 голосов
/ 20 июня 2019

Соединение вашего компонента с хранилищем означает «Вызвать мой компонент или метод рендеринга компонента при изменении реквизита». Сравнение по умолчанию - простая проверка на равенство, которая, вероятно, неверна в ваших данных.

Итак, в вашем приложении вполне возможно, что вы создали новые объекты или массивы, даже если в этом не было необходимости. Это первая и большая проблема, с которой вы столкнулись.

Даже если ваш компонент нуждается в повторном рендеринге, он будет выполнять метод рендеринга, но ваш теневой домен будет таким же, и в большинстве случаев вам не придется делать дорогостоящие операции.

Вы можете выполнить следующие шаги:
- Не создавайте ненужных новых ссылок на объекты и массивы. Ну, это правильное и более длительное решение
- Реализуйте свою собственную проверку на равенство с mapStateToProps. Есть хорошие способы оптимизировать логику селектора, но это зависит от деталей вашего приложения. Лучше следуйте этому посту здесь: https://medium.com/practo-engineering/avoiding-re-renders-in-react-and-optimising-mapstatetoprops-with-reselect-6e199fa7bc73

Должен ли я беспокоиться об этом ненужных повторных подачах?

Это действительно зависит от того, насколько велико ваше приложение. Вероятно, у вас должен быть какой-то тест, проверьте инструменты реагирования.

1 голос
/ 20 июня 2019

Вы можете использовать метод жизненного цикла компонента shouldComponentUpdate, этот метод получает значения nextState и nextProps. При этом вы можете решить, нужно ли обновлять компонент, возвращая true (обновление) или false (не обновлять).

Документация: здесь .

0 голосов
/ 26 июня 2019

Если вы используете react-redux> = 6.0.0, в React DevTools есть ошибка, из-за которой ошибочно отображаются подсвеченные повторные рендеры.

Ложные срабатывания с «Highlight Updates»
https://github.com/facebook/react-devtools/issues/1290

Здесь происходит повторный рендеринг обернутого компонента, но не компонента, на котором вы используете connect.

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