useCallback的作用
在函数组件中,在函数体内我们常常定义一些内嵌的函数。这些函数有一个特性就是在组件每次渲染的时候会被重新定义,这会造成一些性能问题。
React提出useCallback来记住当前定义的函数,并在下次组件渲染的时候返回之前定义的函数而不是使用新定义的函数。
简而言之useCallback就是把我们在函数组件内部定义的函数保存起来,当组件重新渲染时还是使用之前的,就不会被重新定义一次。
验证一下页面渲染时嵌套函数是否会从新定义,需要用到useEffect:
import React from 'react'
import { useState } from 'react'
import { useEffect } from 'react'
export default function Box2() {
let [count,setCount]=useState(1)
let fn=()=>{}
useEffect(()=>{
//组件从新渲染时打印
console.log("组件从新渲染");
},[fn])
return (
<div>
{count}
<button onClick={()=>{setCount(count+1)}}>修改count</button>
</div>
)
}
点击按钮会从新渲染页面,副作用函数依赖于fn函数只有当fn函数变化时才会触发副作用函数并打印,按理来说我们并没有修改fn,但是副作用函数还是运行了,那么就证实了从新渲染页面内嵌的函数会被从新定义。
useCallback的用法
let cb=useCallback(()=>{},dep)
//第一个参数是我们要保存的函数
//第二个参数是依赖项,只有dependencies数组里面的元素的值发生变化时useCallback才会返回新定义的函数,否则useCallback都会返回之前定义的函数。
改进上面代码:
let fn=useCallback( ()=>{},[])
只需要把我们声明的函数用useCallback处理一下,内嵌函数就不会在组件从新渲染时从新定义。
注意
任何优化都会有代价,useCallback也是一样的。当我们在函数组件里面调用useCallback函数的时候,React背后要做一系列计算才能保证当dependencies不发生变化的时候,我们拿到的是同一个函数,因此如果我们滥用useCallback的话,并不会带来想象中的性能优化,反而会影响到我们的性能。
因此在当前组件中没有可能发生更新模板或者属性改变的情况下,组件内的内嵌函数没有必要用useCallback处理。