之前一般都是使用Component的比较多,所以对PureComponent了解比较少。最近在使用PureComponent的时候遇到一些问题,就是setState未触发render渲染的问题;
两者的区别:
它们的区别就是对于状态更新渲染DOM,判断状态是否变化的条件不同,
Component: 使用setState改变状态都会引起dom渲染,而且shouldComponentUpdate默认返回true,就算state和props没有改变也会重新渲染,降低渲染效率;
PureComponent: react优化了shouldComponentUpdate,提高了性能,就是当props或者state改变时,会引起dom重新渲染,当state为数组,对象等引用类型的时候,如果引用没有发生改变,它会认为state是没有发生改变的,也就不会重新渲染。当引用发生变化Component和PureComponent都会引起重新渲染。
import React, { PureComponent, Fragment,Component } from 'react'; export default class UpsertForm extends PureComponent {
state = { arr : [] } onClick = (val) => { const { arr } = this.state; arr.push(val);//push操作或其他操作;此时的arr已经为[true],所以setState不起作用; this.setState({ arr }); console.log(arr);//此时的arr是修改后的内容,但是没有触发render渲染 } render(){ return( <Fragment> <input onChange = {}/> <Button onClick = this.onClick(true)>Edit</Button> </Fragment> ) } } 修改为下面: this.setState({ arr :[...arr] });
React15.3中心增加的PureComponent类,意思为纯组件,减少render操作的次数,可以减少shouldComponent函数使用;
原理:当组件更新时,如果组件的 props 和 state 都没发生改变, render 方法就不会触发,省去 Virtual DOM 的生成和比对过程,达到提升性能的目的。具体就是 React 自动帮我们做了一层浅比较shallowCompare:
if (this._compositeType === CompositeTypes.PureClass) { shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState); }
因此: 易变数据不能使用一个引用;const { items } = this.state;
下面数据不会导致重新渲染:这些例子都是在原对象上进行修改,由于浅比较是比较指针的异同,所以会认为不需要进行重绘
options.push(new Option()) options.splice(idnex, 1); options[i].age = 23;
其他陷阱 可以参考:https://www.jianshu.com/p/33cda0dc316a