一 纯组件
1 使用shouldComponentUpdate对先前的状态和 props 数据与下一个 props 或状态相同,如果两次的结果一直,那么就return false
- 使用纯净组件,pureComponent
PureComponents 负责 shouldComponentUpdate——它对状态和 props 数据进行浅层比较(shallow comparison),如果先前的状态和 props 数据与下一个 props 或状态相同,则组件不会重新渲染。
在 class component 时代,为了性能优化我们经常会选择使用 PureComponent,每次对 props 进行一次浅比较,当然,除了 PureComponent 外,我们还可以在 shouldComponentUpdate 中进行更深层次的控制
3 什么是浅层渲染?
在对比先前的 props 和状态与下一个 props 和状态时,浅层比较将检查它们的基元是否有相同的值(例如:1 等于 1 或真等于真),还会检查更复杂的 JavaScript 值(如对象和数组)之间的引用是否相同。
比较基元和对象引用的开销比更新组件视图要低。因此,查找状态和 props 值的变化会比不必要的更新更快。
import React from 'react';
export default class ApplicationComponent extends React.Component {
constructor() {
super();
this.state = {
name: "Mayank"
}
}
updateState = () => {
setInterval(() => {
this.setState({
name: "Mayank"
})
}, 1000)
}
componentDidMount() {
this.updateState();
}
render() {
console.log("Render Called Again")
return (
<div>
<RegularChildComponent name={this.state.name} />
<PureChildComponent name={this.state.name} />
</div>
)
}
}
class RegularChildComponent extends React.Component {
render() {
console.log("Regular Component Rendered..");
return
}
}
class PureChildComponent extends React.PureComponent {
// Pure Components are the components that do not re-render if the State data or props data is still the same
render() {
console.log("Pure Component Rendered..")
return <div>{this.props.name}</div>;
}
}
在上面的示例中,状态被传播到子组件 RegularChildComponent 和 PureChildComponent。PureChildComponent 是一个纯组件。setstate 在一秒的间隔之后被调用,这将重新触发组件的视图渲染。由于初始 props
和新 props 的值相同,因此组件(PureChildComponent)不会被重新渲染。状态的浅层比较表明 props 或状态的数据没有变化,因此不需要渲染组件,从而提升了性能。
二 使用 shouldComponentUpdate 生命周期事件
这个函数将 nextState 和 nextProps 作为输入,并可将其与当前 props 和状态做对比,以决定是否需要重新渲染。
shouldComponentUpdate(nextProps, nextState) {
if(nextState.age != this.state.age || netState.name = this.state.name) {
return true;
}
return false;
三 React.memo 进行组件记忆(React.memo 是一个高阶组件)
它很像 PureComponent,但 PureComponent 属于 Component 的类实现,而“memo”则用于创建函数组件。
// The following function takes "user" Object as input parameter in props
function CustomisedComponen(props) {
return (
User name: {props.user.name}
User age: {props.user.age}
User designation: {props.user.designation}
)
}
function userComparator(previosProps, nextProps) {
if(previosProps.user.name == nextProps.user.name ||
previosProps.user.age == nextProps.user.age ||
previosProps.user.designation == nextProps.user.designation) {
return false
} else {
return true;
}
}
var memoComponent = React.memo(CustomisedComponent, userComparator);
React.memo 可以利用第二个函数参数进行更精准的控制。如果我们将对象引用作为 props 传递给 memo 组件,则需要一些自定义登录以进行比较。在这种情况下,我们可以将比较函数作为第二个参数传递给 React.memo 函数。假设 props 值(user)是一个对象引用,包含特定用户的 name、age 和 designation。这种情况下需要进行深入比较。我们可以创建一个自定义函数,查找前后两个 props 值的 name、age 和 designation 的值,如果它们不相同则返回 false。
四 使用 useMemo() 进行细粒度性能优化
上面 React.memo() 的使用我们可以发现,最终都是在最外层包装了整个组件,并且需要手动写一个方法比较那些具体的 props 不相同才进行 re-render;
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
useMemo() 返回的是一个 memoized 值,只有当依赖项(比如上面的 a,b 发生变化的时候,才会重新计算这个 memoized 值)
参考文献: https://blog.csdn.net/m0_65121454/article/details/132366339
https://baijiahao.baidu.com/s?id=1757722501241325874&wfr=spider&for=pc