Представьте компонент List
, который отображает список элементов и, при необходимости, выделяет один из них.Как оптимизировать render() в React, когда prop является объектом?
List
имеет следующие реквизиты:
items
- элементы для отображенияhighlightedItemIndex
- индекс выделенного элемента (илиnull
, если ни один не будет выделен)itemProps
- произвольный объект реквизита для прохождения до каждого предмета
List
's render()
метод выглядит следующим образом:
<ul>
{
items.map((item, index) => {
const allItemProps = {
...itemProps,
className: index === highlightedItemIndex ? 'highlighted-item' : ''
};
return (
<Item item={item} itemProps={allItemProps} key={index} />
);
})
}
</ul>
Проблема в том, что каждый раз, когда List
' s render()
называется, Item
получает новый объект для itemProps
вызывая Item
«s render()
называться , что не является необходимым в большинстве случаев, потому что itemProps
на самом деле не изменился (он глубоко соответствует предыдущему itemProps
, но не ===
).
Представьте изображение выше с 1000 элементами, и, когда вы наведете объекты, выделенный элемент изменится соответствующим образом. Каждый раз, когда выделенный элемент меняется, Item
render()
следует вызывать дважды, а не 1000 раз!
Добавление:
shouldComponentUpdate(nextProps) {
return JSON.stringify(nextProps) !== JSON.stringify(this.props);
}
решает эту проблему, но я чувствую, что JSON.stringify
подход может быть довольно дорогим.
Here is a playground Я создал, чтобы продемонстрировать проблему. (У меня есть 5 элементов в списке, а не 1000, но вы получите эту идею.)
Что такое «Реагировать», чтобы оптимизировать рендеринг, когда опорный объект является объектом (inputProps
в этом случае), или, может быть, реквизит объекта не хорошая практика?
Лучшим было бы убедиться, что 'item' - это тот же объект. Я думаю, что в большинстве случаев это возможно. –
В вашем примере, похоже, вы можете избежать использования 'allItemsProps'. Возможно, это может быть ответственностью «Элемента», чтобы знать, какой класс должен быть выделен, а «highlight» может быть свойством элемента. –
Возможно, lodash isEqual feets для вас http://www.webpackbin.com/VkbwSLhPW –