react-hooks的节流与闭包,以及useCallback的用处
创始人
2024-01-25 02:05:56
0
  • 目录

    useThrottle: 封装了一个节流的hook

     useCallback的作用(性能优化)

     不用Hook封装节流方法的情况,看是怎么形成闭包的:


    useThrottle: 封装了一个节流的hook

import { useEffect, useCallback, useRef } from 'react';function useThrottle(fn: Function, delay: any, dep = []) {//用useRef --确保 useCallback里面的值是最新的,如果用useState会形成闭包,导致return不了最新的函数const { current } = useRef({ fn, timer:null })useEffect(function () {current.fn = fn;}, [fn]);return useCallback(function f(this: any) {if (!current.timer) {current.timer = setTimeout(() => {delete current.timer}, delay)current.fn.call(this, arguments)}}, dep)
}export default useThrottle;

使用:

/** 点击事件 */function handleClickJitter(type = '') {if(type == 'debounce') {setText("已处理")}else {console.log("执行一次");setThrottleText(`${new Date().getSeconds()}`)}}return (
);

  •  useCallback的作用(性能优化)

useCalback就是对函数起一个“缓存”作用,当该函数被父组件作为props传递给字组件子组件时,让props“无变化”,因此达到不会让子组件重复渲染的目的。

函数式子组件需要搭配 React.memo使用!!!

无论子组件是pureComponent还是用React.memo进行包裹,都会让子组件render,而配合useCallback使用就能让子组件不随父组件render。

const BtnMemo = React.memo((props: any) => {const { click } = propsconsole.log("渲染一次");return ()
})const throttleJitterCon = (props: IThrottleJitterConProps) => {const [throttleText, setThrottleText] = useState("初始")/** 点击事件 */function handleClickJitter(type = '') {if(type == 'debounce') {setText("已处理")}else {console.log("执行一次");setThrottleText(`${new Date().getSeconds()}`)}}return (
);

 看反例,去掉useCallback的情况:

function useThrottle(fn: Function, delay: any, dep = []) {//用useRef --确保 useCallback里面的值是最新的,如果用useState会形成闭包,导致return不了最新的函数const { current } = useRef({ fn, timer:null })useEffect(function () {current.fn = fn;}, [fn]);return function f(this: any) {if (!current.timer) {current.timer = setTimeout(() => {delete current.timer}, delay)current.fn.call(this, arguments)}}
}

可以看到,执行一次后,btnMemo就会跟着渲染一次。(造成了不必要的渲染,复杂业务逻辑下下,会对项目有影响)

 不用Hook封装节流方法的情况,看是怎么形成闭包的:

const BtnMemo = React.memo((props: any) => {const { click } = propsreturn ()
})const throttleJitterCon = (props: IThrottleJitterConProps) => {const [throttleText, setThrottleText] = useState("初始")/** 节流:在一定时间内只能执行一次 */const throttleFunc = (fn: Function, delay:any) => {let timer: anyreturn useCallback(function(this:any) {console.log("throttleText--useCallback",throttleText); if (!timer) {timer = setTimeout(() => {timer = null}, delay)fn.apply(this, arguments)}},[])}console.log("throttleText++++++++++++",throttleText);/** 点击事件 */function handleClickJitter(type = '') {if(type == 'debounce') {setText("已处理")}else {setThrottleText(`${new Date().getSeconds()}`)}}return (
{handleClickJitter('throttle')},3000)} />
{throttleText}
); }export default throttleJitterCon;

throttleFunc函数里是可以访问外部作用域的 throttleText变量。也验证了闭包的含义:

  • 红宝书:闭包是指有权访问另一个函数作用域中变量的函数
  • MDN: 闭包是指那些能够访问自由变量的函数,这里的自由变量是指外部作用域中的变量

我的源代码: https://github.com/BBbila/my-mixed-bag/tree/main/src/ReatHooks/throttleJitter

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...