hooks 系列五:useCallback

快来加入咱们吧!

"小和山的菜鸟们",为前端开发者提供技术相关资讯以及系列基础文章。为更好的用户体验,请您移至咱们官网小和山的菜鸟们 ( xhs-rookies.com/ ) 进行学习,及时获取最新文章。html

"Code tailor" ,若是您对咱们文章感兴趣、或是想提一些建议,微信关注 “小和山的菜鸟们” 公众号,与咱们取的联系,您也能够在微信上观看咱们的文章。每个建议或是赞同都是对咱们极大的鼓励!前端

前言

这篇文章,咱们主要目的是了解一下 (useCallback) 的使用.react

useCallback

定义

useCallback 返回一个 memoized 回调函数。git

const memoizedCallback = useCallback(fn, deps)
复制代码

useCallback 所需参数github

  • fn :一个函数最终会返回该回调函数,该回调函数仅仅只在 deps 参数发生改变时才会更新。
  • deps : 用于触发 fn 回调函数改变的参数列表。

注意: deps 是一个数组,也就是说改变 fn 的参数能够有不少。web

把内联回调函数及依赖项数组做为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给通过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate)的子组件时,它将很是有用。npm

如何使用

咱们先来看一个简单的例子。数组

这个是一个子组件,接受父类的一个 fn 方法并展现其按钮。浏览器

const ChildComponent = memo(function (props) {
  console.log('child render!')
  return <Button onClick={props.fn}> showTime</Button>
})
复制代码

注意: 这里的 memo 也是一个 Hooks , 详情请见Hook API 索引 – React (reactjs.org)微信

这是一个父组件,里面有一个计数器,一个数字增长按钮,和这个子组件。

function Main() {
  const [count, setcount] = useState(0)

  const ShowTime = () => {
    console.log('now time :' + new Date())
  }

  return (
    <Row style={{ 'flex-direction': 'column', }} > <Col> <Title>index:{count}</Title> </Col> <Col> <Button onClick={() => setcount(count + 1)}>increase</Button> </Col> <Col> <ChildComponent fn={ShowTime} /> </Col> </Row>
  )
}
复制代码

咱们能够看到,在咱们点击 increase 按钮的时候,count 发生了增长,这是正常且合理的。

60cv4-43wz0.gif

可是这个时候咱们打开咱们的浏览器控制台,就会发现子组件 ChildComponent 在不停的 render

这是不合理的,对于咱们来讲,子组件应该只受 childname 该参数的影响,若是该参数函数 fn 没发生改变,咱们就不该该去 render

注意: 这个地方子组件不停 render 的缘由在于,这个 ShowTime 方法在不停的从新建立,而后致使传给子组件的 props 实际上是不同的,所以致使不停 render

这个时候咱们就用到了 useCallback

function Main() {
  const [count, setcount] = useState(0)

  const useMemoryCallback = useCallback(() => {
    console.log('now time :' + new Date())
  }, [])

  return (
    <Row style={{ 'flex-direction': 'column', marginLeft: '10px', }} > <Col> <Title>index:{count}</Title> </Col> <Col> <Button onClick={() => setcount(count + 1)}>increase</Button> </Col> <Col> <ChildComponent fn={useMemoryCallback} /> </Col> </Row>
  )
}
复制代码

这个时候,咱们将这个函数放在 useCallback 中返回,由于 deps 参数为空,因此并无须要改变的,这样子咱们在点击 increase 按钮的时候就不会触发子组件的 render 了。

如何检查

依赖项数组(deps)不会做为参数传给回调函数。虽然从概念上来讲它表现为:全部回调函数中引用的值都应该出如今依赖项数组中。将来编译器会更加智能,届时自动建立数组将成为可能。

咱们推荐启用 eslint-plugin-react-hooks 中的 exhaustive-deps 规则。此规则会在添加错误依赖时发出警告并给出修复建议。

小结

  • useCallback 给咱们带来了记忆函数,结合子组件和 useMemo 能够达到优化组件加载的效果。
  • 若是子组件接受了一个方法做为属性,咱们在使用 React.memo 这种避免子组件作不必的渲染时候,就须要用 useCallback 进行配合,不然 React.memo 将无心义。

下节预告

在下节中,咱们将为你们介绍 hook 规则 ,敬请期待!

相关文章
相关标签/搜索