快来退出咱们吧!

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

"Code tailor" ,如果您对咱们文章感兴趣、或是想提一些倡议,微信关注 “小和山的菜鸟们” 公众号,与咱们取的分割,您也能够在微信上观看咱们的文章。每一个倡议或是同意都是对咱们极大的激励!

前言

这篇文章,咱们次要目标是理解一下 (useCallback) 的应用.

useCallback

定义

useCallback 返回一个 memoized 回调函数。

const memoizedCallback = useCallback(fn, deps)

useCallback 所需参数

  • fn :一个函数最终会返回该回调函数,该回调函数仅仅只在 deps 参数产生扭转时才会更新。
  • deps : 用于触发 fn 回调函数扭转的参数列表。
留神: deps 是一个数组,也就是说扭转 fn 的参数能够有很多。

把内联回调函数及依赖项数组作为参数传入 useCallback,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项扭转时才会更新。当你把回调函数传递给通过优化的并应用援用相等性去防止非必要渲染(例如 shouldComponentUpdate)的子组件时,它将十分有用。

如何应用

咱们先来看一个简略的例子。

这个是一个子组件,承受父类的一个 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 产生了减少,这是失常且正当的。

然而这个时候咱们关上咱们的浏览器控制台,就会发现子组件 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 规定 ,敬请期待!