React PureComponent против компонента

внешний интерфейс React.js

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, потому что это совсем не обязательно