React.js 中的纯组件
我们有一个生命周期方法叫做 shouldComponentUpdate,它默认返回 true(布尔值)。
shouldComponentUpdate 的目的是我们可以自定义实现默认行为,并决定 React 何时应该更新或重新渲染组件。
通常我们使用 state 或 props 值来决定更新周期。React 现在为我们提供了一个 PureComponent,它会比较 state 和 props 来决定更新周期。如果我们用 PureComponent 扩展类,则不需要重写 shouldComponentUpdate。
React 对当前 state 和 props 与新的 props 和 state 进行浅比较,以决定是否继续下一个更新周期。
这有助于提高应用程序的性能。但是,只有在比较每个 state 和 props 有意义的情况下,我们才应该用 PureComponent 扩展类。否则,如果不需要所有 state 和 props 的比较,我们可以自己实现 shouldComponentUpdate。
这个扩展 PureComponent 只适用于基于类的有状态组件。对于函数式组件,我们可以使用纯函数,如下所示:
无状态组件示例
import { pure } from ‘recompose’; export default pure ( (props) => { //custom code return ‘something useful’ ;// your code })
有状态组件示例
import React, {PureComponent} from ‘react’; export default class Test extends PureComponent{ render(){ return ‘’; } }
由于 PureComponent 对 state 和 props 对象进行浅比较,因此如果这些对象包含嵌套的数据结构,则 PureComponent 实现的 shouldComponentUpdate 将返回 false。它甚至可能跳过此组件子树的整体更新。
在这种情况下,子元素也应该是 Pure 的。
因此,嵌套数据结构的比较与 PureComponent 配合得不好。只有当 state 和 props 是简单对象时,它才有效。
如果组件在任何时候对于相同的输入值都返回相同的输出,则可以将其称为纯组件。
如果 state 或 props 引用新的对象,PureComponent 将每次都重新渲染。
应不可变地修改对象,以便使用 PureComponent 成功更新。
如果 shouldComponentUpdate 失败,我们可以使用 forceUpdate 手动重新渲染。如果我们在浅比较中嵌套了对象,可以使用 immutable.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 更改调用,只是为了展示每次如何渲染每个任务。
请检查浏览器控制台日志。
因为 Task 组件没有扩展 PureComponent。React不知道发生了什么变化,所以它每次都会渲染 Task。
所以现在只需用下面的代码更改 Task 组件
Export default class task extends PureComponent => 这解决了 Task 的多次渲染问题,并在没有添加新任务的情况下防止不必要的渲染。