我们有一个称为shouldComponentUpdate的生命周期方法,该方法默认情况下返回true(布尔值)值。
ShouldComponentUpdate的目的是我们可以自定义实现默认行为,并决定何时应更新或重新呈现组件。
通常,我们使用状态或属性值来确定更新周期。React现在为我们提供了一个PureComponent,可以对状态和道具进行比较以决定更新周期。如果我们使用PureComponent扩展类,则不需要重写shouldComponentUpdate。
React对当前状态和props与新的props和state进行了浅浅的比较,以决定是否继续下一个更新周期。
这有助于提高应用程序的性能。但是,只有在比较每个状态和道具时才应使用PureComponent扩展类。否则,如果不需要所有状态和道具比较,我们可以自己实现shouldCompnentUpdate。
此扩展PureComponent仅适用于基于状态类的组件。对于功能组件,我们可以使用如下所示的纯函数-
import { pure } from ‘recompose’; export default pure ( (props) => { //自定义代码 return ‘something useful’ ;// your code })
import React, {PureComponent} from ‘react’; export default class Test extends PureComponent{ render(){ return ‘’; } }
由于PureComponent对状态和props对象进行了浅层比较,因此,如果这些对象包含嵌套的数据结构,则PureComponent的实现的shouldComponentUpdate将返回false。它甚至可以跳过此组件子级的整个子树的更新。
在这种情况下,子元素也应该是Pure。
因此,嵌套数据结构比较不适用于PureComponent。仅当状态和道具是简单对象时,它才起作用。
如果组件在任何时间点针对相同的输入值返回相同的输出,则可以将它们称为纯组件。
如果状态或道具引用了新对象,则PureComponent每次都会重新渲染。
应该不变地修改对象,以使用PureComponent成功进行更新
即使shouldComponentUpdate失败,我们也可以使用forceUpdate手动重新呈现。如果我们在浅层比较中嵌套了对象,请使用imutable.js。
class Test extends React.PureComponent { constructor(props) { super(props); this.state = { taskList: [ { title: 'excercise'}, { title: 'cooking'}, { title: 'Reacting'}, ] }; } componentDidMount() { setInterval(() => { this.setState((oldState) => { return { taskList: [...oldState.taskList] } }); }, 1000); } render() { console.log(“taskList render called”); return (<div> {this.state.taskList.map((task, i) => { return (<Task key={i} title={task.title} />); })} </div>); } } class Task extends React.Component { render() { console.log(“task added”); return (<div> {this.props.title} </div>); } } ReactDOM.render(<Test />, document.getElementById('app'));
每秒之后,我们已经从componentDidMount手动触发了一个prop change调用,以演示每次如何呈现每个任务。
请检查控制台登录浏览器。
因为Task组件没有扩展PureComponent。React不知道更改了什么,因此每次都会渲染Task。
所以现在只需用下面的行更改Task组件
导出默认类任务扩展了PureComponent =>它解决了Task的多次渲染问题,并在没有添加新任务的情况下防止不必要的渲染。