React Hooks 入门教程六:useMemo/useCallback使用,useEffect渲染生命周期执行顺序区别



useMemo ,“创建”一个依赖函数。当其中一个依赖项更改时, useMemo重新计算记忆的值。而不需要在每个渲染进行昂贵的计算。

useMemo作用

useMemo 其实创建了一种数据缓存机制。比如登录页面需要向后台发送含用户名&密码的ajax请求,获取用户登录信息。useMemo 可以设置成只有当用户名密码改变后才向后台重新发送ajax,而在组件重新渲染时使用缓存的用户信息。

useMemo 与 useEffect 生命周期

useMemo 与 useEffect 作用类似,都会在依赖值改变时重新执行,但 useMemo 有一个缓存的返回值。

因此在组织渲染生命周期中,很自然地会把useMemo放到渲染DOM之前执行,如下:

useMemo => 渲染DOM => useEffect

示例:计数器

用我们之前创建的改变IP/PV计数的例子,useMemo和useEffect均不传参,即所有组件渲染时都重新执行,然后输出文字,为了方便演示,我们没有使用 useMemo 默认的返回值。

export function ExampleMemo () {
  let [ ip, setIP ] = useState(0)
  let [ pv, setPV ] = useState(0)

  let memoMsg = 'useMemory here'
  let effectMsg = 'useEffect here'

  useEffect(()=>{
    effectMsg = 'useEffect here:' + Date.now()
  })

  useMemo(()=>{
    memoMsg = 'use Memo here:' + Date.now()
  })

  return (
    <div>
      <hr/><h1>useMemoEffect: IP:{ip}, PV:{pv}</h1>
      <p>{memoMsg}</p>
      <p>{effectMsg}</p>
      <button onClick={()=>{ setIP(ip+1); setPV(pv+1) }}>Add IP</button>
      <button onClick={()=>{ setPV(pv+1) }}>Add PV</button>
    </div>
  )
}

效果:

当点击Add IP或Add PV时,只有useMemo定义的变量会显示到界面上。由此可见,useMemo 是在DOM渲染之前执行的,而useEffect定义的变量没有起作用,则是在DOM渲染之后执行的。

image

依赖值变化

useMemo 标准用法如下,数组传入依赖的项:如下,如果IP没变,返回记住的值。

  let memoIp = useMemo(()=>{
    return 'useMemo ip here:' + Date.now()
  }, [ip])
  
  return (
    <div>
      <hr/><h1>useMemoEffect: IP:{ip}, PV:{pv}</h1>
      <p>{memoMsg}</p>
      <p>{effectMsg}</p>
      <p>{memoIp}</p>
      <button onClick={()=>{ setIP(ip+1); setPV(pv+1) }}>Add IP</button>
      <button onClick={()=>{ setPV(pv+1) }}>Add PV</button>
    </div>
  )

上面的代码只有当点击: Add IP 时, memoIp 的显示值才会改变。

完整示例: https://codesandbox.io/s/flamboyant-lake-nros4?file=/src/ExampleMemoEffect.js

useCallback

useMemo和useCallback接收的参数都是一样,都是在其依赖项发生变化后才执行,都是返回缓存的值,区别在于useMemo返回的是函数运行的结果,useCallback返回的是函数。

useCallback(fn, deps) 与 useMemo(() => fn, deps). 是等价的,

相当于反函数存起来,由用户决定何时使用。


上一篇: React Hooks 入门教程五:useReducer结合useContext 实现 Redux 组件间共享状态管理,简单用户登录示例教程 下一篇: React Hooks 入门教程七:useRef使用与createRef的区别