1. Они почти идентичны, но PureComponent реализует shouldComponentUpdate через неглубокое сравнение prop и state.В некоторых случаях PureComponent можно использовать для повышения производительности
1. так называемый浅比较
(shallowEqual), функцию в исходном коде реакции, а затем сделайте это в соответствии со следующим методомPureComponent
суждение, помогло нам сделать то, что мы должны былиshouldComponentUpdate
дела, сделанные в
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps) || ! shallowEqual(inst.state, nextState);
}
И то, что мы сделали изначально следующим образом, вот суждениеstate
Были ли какие-либо изменения (реквизит тот же), чтобы решить, следует ли повторно отображать, функция здесь наследуется вComponent
компонент, а здесьthis.state.person
это объект, вы найдете,
Когда ссылка на этот объект не изменилась, он не будет сброшен.render
(т.е. третья точка, упомянутая ниже), поэтому мы можем использоватьshouldComponentUpdate
Для оптимизации, если этот метод возвращаетfalse
, указывая на то, что повторно рендерить не нужно, вернутьtrue
затем повторите рендеринг, верните по умолчаниюtrue
shouldComponentUpdate(nextProps, nextState) {
return (nextState.person !== this.state.person);
}
2. Может использоваться в некоторых случаях, указанных выше.PureComponent
Какие конкретные ситуации можно использовать для повышения производительности, а какие недопустимы? Практика приносит истинные знания
3. Ниже показанIndexPage
компонент, который устанавливаетstate
даisShow
, его значение можно изменить нажатием кнопки, результат: вывод во время инициализацииconstructor
,render
,
При первом нажатии на кнопку будет выведен рендер, то есть он будет перерендерен один раз, а также отобразится интерфейс изfalse
отображатьсяtrue
, но когда этот компонент наследуется отPureComponent
Когда вы нажмете еще раз, он не будет выводиться сноваrender
, то есть без повторного рендеринга,
И когда этот компонент наследуется отComponent
, он все равно будет выводитьrender
, он все равно будет перерендерен, на этот разPureComponent
Внутренне оптимизированный
4. То же самое относится кstring
,number
и другие базовые типы данных, поскольку базовые типы данных изменяют значение, даже если оно изменяется
import React, { PureComponent } from 'react';
class IndexPage extends PureComponent{
constructor() {
super();
this.state = {
isShow: false
};
console.log('constructor');
}
changeState = () => {
this.setState({
isShow: true
})
};
render() {
console.log('render');
return (
<div>
<button onClick={this.changeState}>点击</button>
<div>{this.state.isShow.toString()}</div>
</div>
);
}
}
5. Когда этоthis.state.arr
представляет собой массив, а компонент наследуется отPureComponent
Когда инициализация все еще выводитсяconstructor
а такжеrender
, но при нажатии на кнопку никаких изменений в интерфейсе и выводе нетrender
, доказательство не отображается, но из комментариев ниже видно, что каждый клик
После кнопки мы хотим изменитьarr
Значение изменилось, и это значение будет измененоthis.state.arr
, а потому что вPureComponent
середина浅比较
Ссылка на этот массив не меняется, поэтому он не отображается,this.state.arr
также не обновляется, потому что вthis.setState()
Позже значение находится вrender
обновлено, когда
участие здесьthis.setState()
знание
6. Но когда этот компонент наследуется отComponent
Когда инициализация все еще выводитсяconstructor
а такжеrender
, но при нажатии на кнопку интерфейс меняется, то есть мы печатаем обработанныйarr
Значение вывода, и каждый раз, когда нажимается кнопка, оно будет выводиться один разrender
, доказательство было повторно представлено,this.state.arr
Значение было обновлено, поэтому
Мы можем увидеть это изменение в интерфейсе
import React, { PureComponent } from 'react';
class IndexPage extends PureComponent{
constructor() {
super();
this.state = {
arr:['1']
};
console.log('constructor');
}
changeState = () => {
let { arr } = this.state;
arr.push('2');
console.log(arr);
// ["1", "2"]
// ["1", "2", "2"]
// ["1", "2", "2", "2"]
// ....
this.setState({
arr
})
};
render() {
console.log('render');
return (
<div>
<button onClick={this.changeState}>点击</button>
<div>
{this.state.arr.map((item) => {
return item;
})}
</div>
</div>
);
}
}
7. В следующем примере используется扩展运算符
сгенерировать новый массив так, чтобыthis.state.arr
Ссылка изменилась, поэтому вывод при инициализацииconstructor
а такжеrender
, при каждом нажатии кнопки будет выводитьсяrender
, интерфейс также изменится, независимо от того, наследуется ли компонент отComponent
ещеPureComponent
из
import React, { PureComponent } from 'react';
class IndexPage extends PureComponent{
constructor() {
super();
this.state = {
arr:['1']
};
console.log('constructor');
}
changeState = () => {
let { arr } = this.state;
this.setState({
arr: [...arr, '2']
})
};
render() {
console.log('render');
return (
<div>
<button onClick={this.changeState}>点击</button>
<div>
{this.state.arr.map((item) => {
return item;
})}
</div>
</div>
);
}
}
8. Вышеупомянутая ситуация также относится к对象
Случай
2. PureComponent влияет не только на себя, но и на подкомпоненты, поэтому PureComponent лучше всего отображает компоненты
1. Мы позволяемIndexPage
Компонент содержит подкомпонентExample
показыватьPureComponent
Как это влияет на дочерние компоненты
2. Наследование родительского компонентаPureComponent
, дочерние компоненты наследуютComponent
Когда: следующий результат выводится при инициализации какconstructor
,IndexPage render
,example render
, но когда мы нажимаем кнопку, интерфейс не меняется, потому что этоthis.state.person
Ссылка на объект не изменилась, изменились только значения свойств в нем
Итак, хотя дочерний компонент наследуетсяComponent
Невозможно выполнить рендеринг, потому что родительский компонентPureComponent
, родительский компонент вообще не отображается, поэтому и дочерний компонент не отображается
3. Наследование родительского компонентаPureComponent
, дочерние компоненты наследуютPureComponent
Когда: поскольку рендеринг не выполняется при выполнении родительского компонента, он эквивалентен перехвату, поэтому дочерний компонентPureComponent
ещеComponent
На результат это никак не влияет, интерфейс остался прежним
4. Наследование родительского компонентаComponent
, дочерние компоненты наследуютPureComponent
Когда: результаты, и мы ожидаем так же, как этот выход будет инициализироватьconstructor
,IndexPage render
,example render
, но появляется только при нажатииIndexPage render
, потому что родительский компонентComponent
, поэтому родительский компонент будет отображаться, но
Когда родительский компонент передает значение дочернему компоненту, потому что дочерний компонентPureComponent
, так и будетprop
Делая поверхностное сравнение, нашел этоperson
Ссылка на объект не изменилась, поэтому он не будет перерисовываться, а отображение интерфейса отображается дочерним компонентом, поэтому интерфейс не изменится.
5. Наследование родительского компонентаComponent
, дочерние компоненты наследуютComponent
Когда: инициализация выводитсяconstructor
,IndexPage render
,example render
, когда мы нажимаем кнопку в первый раз, интерфейс меняется, и он не изменится в дальнейшем, потому что мы всегда устанавливали его на sxt2, но каждый раз, когда мы нажимаем
будет выводитьIndexPage render
,example render
,потому что
Он будет отображаться каждый раз, независимо от родительского или дочернего компонента.
6. Итак, как сказано в четвертом предложении ниже, еслиstate
а такжеprop
Если он продолжает меняться, рекомендуется использоватьComponent
,а такжеPureComponent
Лучший компонент дисплея
//父组件
import React, { PureComponent, Component } from 'react';
import Example from "../components/Example";
class IndexPage extends PureComponent{
constructor() {
super();
this.state = {
person: {
name: 'sxt'
}
};
console.log('constructor');
}
changeState = () => {
let { person } = this.state;
person.name = 'sxt2';
this.setState({
person
})
};
render() {
console.log('IndexPage render');
const { person } = this.state;
return (
<div>
<button onClick={this.changeState}>点击</button>
<Example person={person} />
</div>
);
}
}
//子组件
import React, { Component } from 'react';
class Example extends Component {
render() {
console.log('example render');
const { person } = this.props;
return(
<div>
{person.name}
</div>
);
}
}
3. Если есть ссылочные типы, такие как массивы и объекты, перед рендерингом ссылка будет другой.
4. Если prop и state меняются каждый раз, то PureComponent не так эффективен, как Component, потому что поверхностное сравнение тоже требует времени.
5. Если есть shouldComponentUpdate, выполнить его.Если такого метода нет, он будет судить, является ли он PureComponent.Если да, то выполнить поверхностное сравнение.
1. Унаследовано отComponent
компонент, еслиshouldComponentUpdate
вернутьfalse
, он не будет отображаться, унаследован отPureComponent
Нам не нужно оценивать компоненты вручнуюprop
а такжеstate
, так что вPureComponent
используется вshouldComponentUpdate
Будет следующее предупреждение:
IndexPage has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.
Это также легче понять, просто неPureComponent
используется вshouldComponentUpdate
, потому что это совсем не обязательно