用法由来
当数据重新赋值时,整个组件会刷新渲染,当数据功能复杂且多,且部分数据无需刷新时,会被强制刷新,造成性能浪费,也可能会产出bug。那么这时候就需要用上useCallback和useMemo来缓存不需要更新的数据,形成memoized值,也就是缓存的值。memo则是用于子组件不重新渲染
共同作用
不同形式的减少重复渲染
memo用法
假设组件Parent,里面有个子组件Child
const Parent = () => {
const [num,setBum] = useState(0)
return (
<View>
<Button onClick={()=> setNum(num+1)} >
<Child />
</View>
)
}
const Child = () => {
console.log('child load')
return (
<View>child text</View>
)
}
- 点击Button,Child会随着Parent刷新渲染,控制台打印
// child load
- 使用memo后
const Child = memo(() => {
console.log('child load')
return (
<View>child text</View>
)
})
- 点击button后Child不会重新渲染,控制台无打印
- memo是一个函数,参数二是控制组件是否刷新的选填扩展函数,用法和shouldComponentUpdate一样
useCallback 的用法
同上有组件Parent,里面有个子组件Child
const Parent = () => {
const [num,setBum] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
return (
<View>
<Button onClick={clickBtn} >
<Child call={clickBtn} />
</View>
)
}
const Child = memo((call) => {
console.log('child load')
return (
<View onClick={call}>child text</View>
)
})
- 点击Button,Child会随着Parent刷新渲染,控制台打印
// child load
由于打印了推论在给子组件传递函数后memo会无效
- 使用useCallback后
const Parent = () => {
const [num,setBum] = useState(0)
const clickBtn = useCallback(() => {
setNum(num+1)
},[]) //[]可选填依赖项,不填里面的num是不会更新的,永远都是0
return (
<View>
<Button onClick={clickBtn} >
<Child call={clickBtn} />
</View>
)
}
const Child = memo((call) => {
console.log('child load')
return (
<View onClick={call}>child text</View>
)
})
- 点击button后Child不会重新渲染,控制台无打印
- useCallback参数二[ ]是可选填依赖项,不填里面的num是不会更新的,永远都是num得初始值0,ex: 如果填了[num],那么clickBtn函数会跟着num的更新而更新。
useMemo用法
同上有组件Parent,里面有个子组件Child
const Parent = () => {
const [num,setBum] = useState(0)
return (
<View>
<Button onClick={clickBtn} >
<Child num={num + 1} call={clickBtn} />
</View>
)
}
const Child = memo((num) => {
console.log('child load')
return (
<View>child text {num}</View>
)
})
- 点击Button,Child会随着Parent刷新渲染,控制台打印
// child load
由于打印了推论出在给子组件传递变量的情况下memo会无效
- 使用useMemo后
const Parent = () => {
const [num,setBum] = useState(0)
const mockData = useMemo(() => ({
newNum: num + 1
}),[]) // []可选填依赖项,不填里面的num是不会更新的,永远都是0,那么newNum永远是1
return (
<View>
<Button onClick={clickBtn} >
<Child num={mockData.newNum} call={clickBtn} />
</View>
)
}
const Child = memo((call) => {
console.log('child load')
return (
<View onClick={call}>child text</View>
)
})
- 点击button后Child不会重新渲染,控制台无打印,避免了无意义渲染
- useMemo参数二[ ]是可选填依赖项,不填里面的num是不会更新的,永远都是num得初始值0,ex: 如果填了[num],那么mockData对象会跟着num的更新而更新。
区别
- memo用于缓存组件
- useCallback用于缓存函数
- useMemo用于缓存数据对象,写法需要return 对象{} ,由于ES6语法可简写成() => ({}) 相当于
function f1() {
return {}
}
觉得还不错记得点个赞,与君加油