当使用 component 时,父组件的 state 或 prop 更新时,无论子组件的state、prop 是否更新,都会触发子组件的更新,这会形成很多没必要的 render,浪费很多性能
React.Component 并未实现 shouldComponentUpdate(),component 是需要开发者在 shouldComponentUpdate 钩子函数中自己写 render 逻辑的
pureComponent 不需要开发者使用 shouldComponentUpdate,通过 prop 和 state 的浅比较(shallowEqual)来实现 shouldComponentUpdate。 浅比较(shallowEqual):是react源码中的一个函数,它代替了 shouldComponentUpdate 的工作, 只比较外层数据结构,只要外层相同,则认为没有变化,不会深层次比较数据。
为什么要使用pureComponent?
主要在于 pureComponent 可以减少不必要的 render,从而提高了性能,另外就是,不需要再手写 shouldComponentUpdate 里面的代码,从而节省了代码量;当组件更新时,pureComponent的 shouldComponentUpdate 函数里对 props 和 state 做了一个浅对比,如果组件的 state和 prop 都没有发生变化,就不会触发 render 方法,省去了 virtual DOM 的 diff 和重新生成的过程,从而提升了性能;也正是因为是浅对比,所以不适合使用在含有多层嵌套对象的 state 和 prop 中。
React.PureComponent 中的 shouldComponentUpdate() 仅作对象的浅层比较。如果对象中包含复杂的数据结构,则有可能因为无法检查深层的差别,产生错误的比对结果。仅在你的 props 和 state 较为简单时,才使用 React.PureComponent,或者在深层数据结构发生变化时调用 forceUpdate() 来确保组件被正确地更新。你也可以考虑使用 immutable 对象加速嵌套数据的比较。当遇到复杂数据结构时,可以将一个组件拆分成多个 pureComponent,以这种方式来实现复杂数据结构,以期达到节省不必要渲染的目的。
pureComponent的缺点:由于进行的是浅比较,可能由于深层的数据不一致导致而产生错误的否定判断,从而导致页面得不到更新;
React.memo 为高阶组件。它与 React.PureComponent 非常相似,但它适用于函数组件,但不适用于 class 组件。如果你的函数组件在给定相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果。
import React,{ memo } from 'react';
const MemoSon = memo (function Son(props) {
console.log('MemoSon rendered : ' + Date.now());
return (<div>{ props.val }</div>)
})
export default MemoSon
默认情况下其只会对复杂对象做浅层对比,如果你想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现。
function MyComponent(props) {
/* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
/* 如果把 nextProps 传入 render 方法的返回结果与将 prevProps 传入 render 方法的返回结果一致则返回 true,否则返回 false */
}
export default React.memo(MyComponent, areEqua
此方法仅作为性能优化的方式而存在。但请不要依赖它来“阻止”渲染,因为这会产生 bug。 与 class 组件中 shouldComponentUpdate() 方法不同的是,如果 props 相等,areEqual 会返回 true;如果 props 不相等,则返回 false。这与 shouldComponentUpdate 方法的返回值相反。