react 进阶hook 之 useCallback hook

简介: 原因就是在于那个回调函数,还记得属性传入一个函数,如果是直接在事件后面绑定那么每一次render的时候就会重新生成一个函数。并且每一次的函数的地址都不一样,所以这就是为啥 父组件渲染,子组件也会跟着渲染的根本原因。

callback 相信大家都不陌生——回调函数 ,但是 callback hooks 的作用是啥呢?用于得到一个固定引用值的函数,通常用它进行性能优化


语法


const func = useCallback(fn, deps)


  • 参数 fn: 一个函数,需要保存的函数引用


  • 参数 deps: 一个数组,保存函数里面的依赖,如果依赖变化,那么函数的引用地址就会发生变化,否则不执行,这个的用法有点和 effect hooks 类似


案例


有这么一个场景,我们在一个函数组件中,引用了一个类组件(纯组件,数据发生变化才会执行rendrer,),然后在函数组件中做以下事情


。类组件传递数据不改变

。函数组件数据可以自己改变


代码如下:


import React, { PureComponent, useState } from 'react'
interface ITestClassCompP {
  // 数字
  count: number,
  // 点击更改数据
  onClick: () => void
}
// 这是一个存组件,只有props 或者state 变化的时候才会render
class TestClassComp extends PureComponent<ITestClassCompP> {
  render() {
    console.log('TestClassComp 组件渲染了');
    return (
      <div>
        <h1>我是类组件,数据从函数组件穿过来,值是  {this.props.count}</h1>
        <button onClick={this.props.onClick}> + 1 </button>
      </div>
    )
  }
}
// 测试组件
export function TestCallbackHook() {
  // 状态值
  const [count, setCount] = useState(0)
  console.log('TestCallbackHook 组件渲染了');
// 输入框的值
  const [inputVal, setInputVal] = useState(0)
  return (
    <>
      <TestClassComp
        count={count}
        onClick={() => {
          setCount(count + 1)
        }} />
      <input
        value={inputVal}
        type="number"
        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
          setInputVal(parseInt(e.target.value))
        }} />
    </>
  )
}


效果


20210408095154538.gif


从代码中,我们可以知道,我们点击+ 1 按钮的时候,两个组件需要渲染,但是输入框的数据改变是不应该渲染子组件的,因为我们的count 数据是没有变化的,这是为啥呢?


原因就是在于那个回调函数,还记得属性传入一个函数,如果是直接在事件后面绑定那么每一次render的时候就会重新生成一个函数。并且每一次的函数的地址都不一样,所以这就是为啥 父组件渲染,子组件也会跟着渲染的根本原因。


如何解决


还记得类组件是如何解决这个问题么? 在类组件中,我们的事件绑定函数定义是直接使用 esnext 的语法,定义出来,这样就不会导致每一次的函数引用地址不变了,那么在函数组件可以使用么?


答案是: 不行,有兴趣的自己去尝试


20210408100423656.png


使用 callback hooks 来保存引用


改造函数,如下


20210408100603907.png


最终效果


20210408100936975.gif


这个效果才是我们想要的!

相关文章
|
1月前
|
前端开发
React中useEffect、useCallBack、useLayoutEffect
React中useEffect、useCallBack、useLayoutEffect
|
1月前
|
前端开发
掌握React中的useCallback:优化性能的秘诀
掌握React中的useCallback:优化性能的秘诀
|
1月前
|
前端开发 JavaScript
【边做边学】React Hooks (二)——useEffect Hook
【边做边学】React Hooks (二)——useEffect Hook
|
1月前
|
前端开发 JavaScript
React中useEffect Hook使用纠错
React中useEffect Hook使用纠错
22 0
|
1月前
|
前端开发 中间件 数据安全/隐私保护
React路由进阶方法
React路由进阶方法
35 1
|
1月前
|
自然语言处理 前端开发 JavaScript
说说你对 React Hook的闭包陷阱的理解,有哪些解决方案?
说说你对 React Hook的闭包陷阱的理解,有哪些解决方案?
61 0
|
6月前
|
自然语言处理 前端开发 JavaScript
美丽的公主和它的27个React 自定义 Hook(四)
美丽的公主和它的27个React 自定义 Hook(四)
|
6月前
|
存储 前端开发 数据可视化
美丽的公主和它的27个React 自定义 Hook(三)
美丽的公主和它的27个React 自定义 Hook(三)
|
6月前
|
存储 JSON 前端开发
美丽的公主和它的27个React 自定义 Hook(二)
美丽的公主和它的27个React 自定义 Hook(二)
|
6月前
|
前端开发 JavaScript API
美丽的公主和它的27个React 自定义 Hook(一)
美丽的公主和它的27个React 自定义 Hook(一)