React useCallback使用教程

 更新时间:2023年01月05日 10:53:29   作者:折桂怀橘  
useCallback是react中比较重要的一个hook,useCallback 用来返回一个函数,在父子组件传参或者通用函数封装中,起到举足轻重的作用

开始之前请注意这句话:任何优化都会增加复杂性,任何过早添加的优化都会带来风险,因为优化后的代码可能会多次更改

useEffect

相关作用:监听 & 初始化

//最简单用法
   useEffect(() => {
     //只有方法体,相当于componentDidMount和componentDidUpdate中的代码
    document.title = count;
  })
  //加返回值用法
  useEffect(() => {
    //添加监听事件,相当于componentDidMount和componentDidUpdate中的代码
    window.addEventListener('resize', onChange, false);
    //返回的函数用于解绑事件,相当于componentWillUnmount中的代码
    return () => {
      window.removeEventListener('resize', onChange, false)
    }
  })
  //加空数组参数用法
  useEffect(() => {
    // 相当于 componentDidMount
    window.addEventListener('resize', onChange, false)
    return () => {
      // 相当于 componentWillUnmount
      window.removeEventListener('resize', onChange, false)
    }
  }, []);
  //加监听值用法
  useEffect(() => {
   //只有当count的值发生变化,此函数才会执行
    console.log(`count change: count is ${count}`)
  }, [ count ]);

useCallback

先看一个最简单的例子:

// 用于记录 getData 调用次数
let count = 0;
function App() {
  const [val, setVal] = useState("");
  function getData() {
    setTimeout(()=>{
      setVal('new data '+count);
      count++;
    }, 500)
  }
  useEffect(()=>{
    getData();
  }, []);
  return (
    <div>{val}</div>
  );}

getData模拟发起网络请求。在这种场景下,没有useCallback什么事,组件本身是高内聚的。

如果涉及到组件通讯,情况就不一样了:

// 用于记录 getData 调用次数
let count = 0;
function App() {
  const [val, setVal] = useState("");
  function getData() {
    setTimeout(() => {
      setVal("new data " + count);
      count++;
    }, 500);
  }
  return <Child val={val} getData={getData} />;}function Child({val, getData}) {
  useEffect(() => {
    getData();
  }, [getData]);
  return <div>{val}</div>;}

就这么轻轻松松,一个死循环就诞生了…

先来分析下这段代码的用意,Child组件是一个纯展示型组件,其业务逻辑都是通过外部传进来的,这种场景在实际开发中很常见。

再分析下代码的执行过程:

  • App渲染Child,将val和getData传进去
  • Child使用useEffect获取数据。因为对getData有依赖,于是将其加入依赖列表
  • getData执行时,调用setVal,导致App重新渲染
  • App重新渲染时生成新的getData方法,传给Child
  • Child发现getData的引用变了,又会执行getData
  • 3 -> 5 是一个死循环

如果明确getData只会执行一次,最简单的方式当然是将其从依赖列表中删除。但如果装了 hook 的lint 插件,会提示:React Hook useEffect has a missing dependency

useEffect(() => {
  getData();}, []);

实际情况很可能是当getData改变的时候,是需要重新获取数据的。这时就需要通过useCallback来将引用固定住:

const getData = useCallback(() => {
  setTimeout(() => {
    setVal("new data " + count);
    count++;
  }, 500);}, []);

上面例子中getData的引用永远不会变,因为他它的依赖列表是空。可以根据实际情况将依赖加进去,就能确保依赖不变的情况下,函数的引用保持不变。

还有一个要注意的是

在开始监听一个鼠标的移动的时候,想要删除这个监听不生效,由于是, 加入useState导致组件再次渲染 handleMouse 函数在次渲染, handleMouse 作为组件内的方法, 会跟着一同再次渲染, 并且在内存里, 再次渲染出的 clickFunc !== 前clickFunc.

所以removeEventListener无法解除绑定, 再次addEventListener则会绑定一个新方法.

document.addEventListener('mousemove',handleMouse,true)

解决方案 : useCallback 缓存改方法 这时候的 document.removeEventListener(‘mousemove’,handleMouse,true) 中的handleMouse 和添加中的方法就是一个了,就能删除了。

onst handleMouse= useCallback(() => {
//xxxx
    console.log("clicking");
  }, []);

到此这篇关于React useCallback使用教程的文章就介绍到这了,更多相关React useCallback内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 实现React单页应用的方法详解

    实现React单页应用的方法详解

    今天我们来学习React是如何构建起一个单页应用的,React作为目前最流行的前端框架之一,其受欢迎程度不容小觑,从这门框架上我们可以学到许多其他前端框架所缺失的东西,也是其创新性所在的地方,比如虚拟DOM、JSX等。下面一起来看看。
    2016-08-08
  • 基于antd的autocomplete的二次封装查询示例

    基于antd的autocomplete的二次封装查询示例

    这篇文章主要为大家介绍了基于antd的autocomplete的二次封装查询示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • React项目动态设置title标题的方法示例

    React项目动态设置title标题的方法示例

    这篇文章主要介绍了React项目动态设置title标题的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 探究react-native 源码的图片缓存问题

    探究react-native 源码的图片缓存问题

    本篇文章主要介绍了探究react-native 源码的图片缓存问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • React Native 使用Fetch发送网络请求的示例代码

    React Native 使用Fetch发送网络请求的示例代码

    本篇文章主要介绍了React Native 使用Fetch发送网络请求的示例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • React学习之JSX与react事件实例分析

    React学习之JSX与react事件实例分析

    这篇文章主要介绍了React学习之JSX与react事件,结合实例形式分析了React中JSX表达式、属性、嵌套与react事件相关使用技巧,需要的朋友可以参考下
    2020-01-01
  • React 之 Suspense提出的背景及使用详解

    React 之 Suspense提出的背景及使用详解

    这篇文章主要为大家介绍了React 之 Suspense提出的背景及使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 在React项目中使用Eslint代码检查工具及常见问题

    在React项目中使用Eslint代码检查工具及常见问题

    这篇文章主要介绍了在React项目中使用Eslint代码检查工具及常见问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • react项目打包后点击index.html页面出现空白的问题

    react项目打包后点击index.html页面出现空白的问题

    这篇文章主要介绍了react项目打包后点击index.html页面出现空白的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 在React项目中使用iframe嵌入一个网站的步骤

    在React项目中使用iframe嵌入一个网站的步骤

    本文介绍了如何在React项目中通过iframe嵌入百度网站的步骤,首先创建一个Baidu.js组件,并在该组件中设置iframe来加载百度,然后在App.js中引入并使用Baidu组件,还讨论了因安全策略可能无法加载某些网站的问题,需要的朋友可以参考下
    2024-09-09

最新评论