踩坑场景
在使用useEffect的时候
useEffect(() => {params()},[])
期望结果是组件初始化执行params(),但是react会有warning警告deps需要有params,官方对useEffect的解释是默认情况下,effect 将在每轮渲染结束后执行,但你可以选择让它 在只有某些值改变的时候 才执行。但是这样写会导致重复的执行useEffect,因为当params定义在组件内部时,任何的state更新都会导致组件重新渲染,那么每次拿到的params都是新的函数引用,那对于useEffect而言每次都会更新执行内部函数,但是我们期望的并不是state更新就去执行不相关的effect。
区别
useMemo,useCallback,useEffect
const memo = useMemo(()=> deps, [deps])当deps变化的时候,会执行第一个函数并返回一个memo值const memoFn = useCallback(() => {console.log(deps)}, [deps])当deps变化的时候,会重新定义第一个参数的函数,并不会执行这个函数useEffect(() => {console.log(deps)},[deps])当deps变化的时候,会执行第一个函数
PS: useMemo与useCallback使用方式上非常相似
const memo = useMemo(() => () => {},[deps])
等同于
const memo = useCallback(() => {},[deps])
解决
通过上述区别不难看出,useCallback与useMemo就可以解决这个问题,它在deps改变后并不会立马执行函数,而是重新定义该函数,并且返回出去,在需要使用时再调用即可。那么文章开头的params()函数,就可以const params = useCallback(oldParams,[deps])当deps改变时,才会重新定义params函数,而不是像以前定义写法一样在修改无关的state时,触发了组件的渲染而导致params函数又被重新定义