Я пытаюсь понять на практике, как shallow
сравнение опор работает в React.PureComponent
в случае, когда опора является объектом.Я прочитал две интерпретации:
- Проверяется только тот факт, что новая опора указывает на тот же объект, то есть ссылка остается неизменной.
- Свойства объекта сравниваются.
В любом случае мой пример должен соответствовать любой из интерпретаций.Но по какой-то причине мой компонент все еще перерисовывается.
Вот что у меня есть.
Parent.js
import React from 'react'
import {getItems} from '../utils/data'
import Child from './Child'
import Filter from './Filter'
class Parent extends React.Component {
state = {
filter: undefined,
items: []
}
handleFilterChange = filter => {
this.setState(
{filter},
() => getItems(filter, items => this.setState({items})
)
}
render() {
return (
<div>
<Filter filter={this.state.filter} onFilterChange={this.handleFilterChange} />
<Child items={this.state.items} />
</div>
)
}
}
Child.js
class Child extends React.PureComponent {
render() {
return (
console.log('RENDER')
...
)
}
}
При изменении filter
дважды запускается метод render
компонента Parent
:
- Когдасостояние
Parent
обновляется новыми filter
. - Когда выбираются новые
items
и обновляется состояние Parent
.
Теперь,поскольку мой Child
- это PureComponent
, я ожидал бы, что он будет перерисован только во второй раз, а не в первый.Но на самом деле при повторном рендеринге оба раза.
items
- это массив объектов, например:
[
{title: 'aaa', index: 0, group: 'filter1'},
{title: 'bbb', index: 1, group: 'filter2'}
]
Итак, я ожидал бы, что PureComponent
НЕ будет отображаться, если толькоfilter
обновляется, поскольку:
items
- это тот же массив, который хранится в состоянии компонента Parent
; - Содержимое
items
массив не изменяется, т.е. объекты абсолютно одинаковы.
Почему мой компонент Child
рендерится дважды тогда?