当组件的任一属性"发生改变"或者调用 setState 时,React 的组件就会被更新。
props改变或者state改变都会导致组件被更新, 重新渲染。
注意:因为 React 的更新是只要变动,render 的内容就全量更新,这意味着当发生上述组件更新时,该组件或者是当前页面下的所有节点都将逐个重新渲染。
控制组件的更新是写 React 最重要的一环之一,特别是在面临着大数据渲染时,避免不必要的重复渲染或者函数调用可能直接影响到整个页面的性能。
在类组件中,我们可以对shouldComponentUpdate生命周期函数做操作, 通过返回true or false来阻止组件的更新。也可以使用pureComponent来优化组件更新,通过props和state的浅对比来实现 shouldComponentUpate()。
在函数组件中可以使用useMemo,或者 React.memo 来优化组件的更新渲染。
React.memo
**React.memo** 是直接从 React 库中导出的方法。
用 React.memo 包裹的组件在渲染时,会先对组件更新前后的每个属性进行对比, 若有属性发生变化,则调用该组件的 render,在 Function Component 中则是直接执行函数本身。
import React, {memo} from 'react'
let num = 1
// const Child = (props => { // 没有加 memo
const Child = memo(props => { // 加了 memo
const { name } = props
console.log('render child ', name) // 当触发重渲染的时候会打印
return (
<div>{name}</div>
)
})
const Father = props => {
console.log('render father') // 当触发重渲染的时候会打印
const [a, setA] = useState('a')
const [b, setB] = useState('b')
const hanldePlus = () => {
setA('a' + num)
setB('b')
num++
}
return (
<div>
<button style={{padding: '15px'}}>plus</button>
<Child name={a} />
<Child name={b} />
</div>
)
}
总结:
我们可以使用React.memo对传递给子组件的属性进行比较, 来优化子组件的更新。
但是当传递给子组件的属性中包含函数时, 由于父组件更新会导致函数重新创建, 所以我们需要用到useCallback函数去记忆函数。使其在父组件render的时候不会随意重新创建。
结合React.memo和useCallback可以有效的防止组件的不必要渲染,更新操作。