React useEffect,useCallback,useMemo的个人理解

本文记录个人对React的hook中useEffect,useCallback,useMemo的个人理解。
三者的定义:

useEffect(didUpdate, deps);

const memoizedCallback = useCallback(() => {
    doSomething(params);
  }, deps);

const memoizedValue = useMemo(() => computeExpensiveValue(params), deps);

三者的第二个deps是一个数组,表示依赖的参数列表,当依赖列表中任一参数变化时,则重新执行前面的函数。如deps = [a,b],表示a或者b发生变化则执行前面的函数(注意对象和值的变化方式不同)。
deps=[]时,表示只会在组件第一次渲染成功之后执行一次。

useEffect

didUpdate是一个包含命令式、且可能有副作用代码的函数。
didUpdate是组件渲染成功且deps依赖参数发生变化时执行的函数,也就是说useEffect会执行didUpdate
didUpdate可以没有返回值,只是执行didUpdate的内容。
didUpdate当它有返回值时,返回值必须是个可执行的函数,目的是用于清除didUpdate执行过程中产生的订阅或者计时器等资源。同时如果didUpdate多次触发,则在每次重新执行前都会先执行返回的可执行函数。(官方称之为清除effect)
如下:

useEffect(() => {
  const timer = setInterval(()=>{
    console.log('effect')
  }, 10*1000);
  return () => {
    // 清除定时器
    clearInterval(timer);
  };
});

因此对于useEffect来说,didUpdate时deps有变化时就是执行的,didUpdate若有返回值时,则在下次执行didUpdate时会先执行其返回的函数。

useCallback

返回一个memoized回调函数,我的理解即返回一个函数的句柄,等同于函数的变量,因此你可以使用memoizedCallback()进行执行该函数或者传递给事件和子组件,这里可以推荐绝大多数事件或者子组件的方法使用useCallback,避免组件更新重复渲染。
因此useCallback中的doSomething并不会在定义时就执行,而是需要手动调用返回的memoizedCallback才是真的执行。简单理解为useCallback定义了一个函数,仅在deps发生变化时重新定义该函数,否则该函数的变量不会变化,事件和子组件内容也就不用重新绑定或者渲染。

useMemo

返回一个memoized值,useMemo函数每当deps发生变化时都会调用执行computeExpensiveValue的内容,这是与useCallback最大的不同,useCallback不执行doSomething的内容,只是重新刷新函数句柄。
因此在官方上有这样的一个等式:
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)
这应该看懂了吧。deps发生变化时,useCallback返回的是一个可执行fn的句柄,而useMemo则是执行()=>fn,但是因为返回的是fn函数,因此当调用这两种时其实执行的是相同的fn函数内容。

总结

我自身对三者的理解是基于hook定义时:首参是否执行和各自返回内容的作用与差异进行理解,如果本文无法准确描述清楚,建议你也可以从这两方面进行入手分析三者之间的区别和用途。
当然这样的解释和理解可能无法去解释什么情况用useEffect、useCallback、useMemo。但是作为开发者而言,理解hook其定义的差异,亦可理解其不同的用途目的,也就能区分清楚三者各自应在什么情况下进行使用。

你可能感兴趣的:(react.js,前端,hook)