React.memo
如果你的组件在相同 props
的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo
中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React
将跳过渲染组件的操作并直接复用最近一次渲染的结果。
React.memo
仅检查 props
变更
例如我们渲染一个斐波那契数列的第40位的值,这是一个很耗时的递归操作,在父组件中修改state
,我们知道state
变了,会导致组件重新渲染,此时Fib
组件也会重新渲染,会去重新计算斐波那契数列的值,由于计算非常耗时,此时页面会夯住;
import React from 'react'
class Fib extends React.Component {
constructor(props){
super(props)
}
fib = (n) => {
if (n == 1 || n == 2) return 1
return this.fib(n - 1) + this.fib(n - 2)
}
componentDidUpdate() {
console.log('重新渲染了')
}
render() {
return <div>
<div>{this.fib(this.props.n)}</div>
</div>
}
}
class Comp extends React.Component {
constructor(props){
super(props)
this.state = {
count: 0
}
}
render(){
return <div>
<p>{this.state.count}</p>
<button onClick={()=>{this.setState({count: this.state.count + 1})}}>+1</button>
<Fib n={40}></Fib>
</div>
}
}
export default Comp
查看结果发现,每当我们点击按钮,Fib
组件都会重新渲染并计算值,性能很差;
而如果我们使用React.memo
高阶组件包装一下Fib
,此时页面检测到实际上Fib
组件的props
属性n
并没有发生改变,则跳过渲染组件的操作并直接复用最近一次渲染的结果
只需要这么包一下
// ...
const FibMemo = React.memo(Fib)
class Comp extends React.Component {
constructor(props){
super(props)
this.state = {
count: 0
}
}
render(){
return <div>
<p>{this.state.count}</p>
<button onClick={()=>{this.setState({count: this.state.count + 1})}}>+1</button>
<FibMemo n={40}></FibMemo>
</div>
}
}
通过结果可以看到,使用React.memo
包装了之后,组件没有重复渲染,父组件的行为也正常
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com