我的编程空间,编程开发者的网络收藏夹
学习永远不晚

useEvent降低Hooks负担的原生Hook分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

useEvent降低Hooks负担的原生Hook分析

这篇文章主要讲解了“useEvent降低Hooks负担的原生Hook分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“useEvent降低Hooks负担的原生Hook分析”吧!

没有 useEvent 的时候

我们先看看不用 useEvent 的情况:

function Chat() {  const [text, setText] = useState('');  // ???? Always a different function  const onClick = () => {    sendMessage(text);  };  return <SendButton onClick={onClick} />;}

其中点击事件的回调函数 onClick 中需要读取当前键入的文本text,这里的onClick随着组件重新渲染一次次地重新创建,每次都会是不一样的引用,这显然带来了性能损耗,如果你想对其进行优化,你可能会这样做:

function Chat() {  const [text, setText] = useState('');  // ???? A different function whenever `text` changes  const onClick = useCallback(() => {    sendMessage(text);  }, [text]);  return <SendButton onClick={onClick} />;}

通过 useCallback 返回一个 memoized 回调函数。

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

最终使得onClick的引用始终不变但是!

onClcik这个方法有需要保证每次都要拿到最新的、正确的text,所以他的deps中就自然是设置了text&mdash;&mdash; 坏了,“又回到最初的起点~”。随着每一次keystrokeonClick又变成了上面的情况:

 Always a different function

但你又不能将其从deps中移除,移除了他就只能拿到text的初始值,失去了他本该有的功能...

小 useEvent 来给他整个活

useEvent就是为了解决此类问题,所以他干脆不要deps了,他就是一直返回一个相同的函数引用,哪怕text发生变化。当然,保证它也能拿到最新的、正确的**text**

function Chat() {  const [text, setText] = useState('');  // ✅ Always the same function (even if `text` changes)  const onClick = useEvent(() => {    sendMessage(text);  });  return <SendButton onClick={onClick} />;}

现在好了:

  • onClick 的引用始终是同一个

  • 保证每次都能拿到最新的、正确的 text

当然还有其他一些场景,但是大致需求原理相同,就是不想让A因为b变化而总是重新加载,但是又因为要拿到b恰当的值,所以deps中必须b,导致不得不重新加载,掉进了“圈圈圆圆圈圈~”的陷阱。更多场景这里就不再赘述。更多案例可查看文末的学习资源~

总而言之,用useEvent给他裹上就是香,就是可以同时达到上面两个效果:

  • 引用不变

  • 拿到恰当的值

这是咋做到的????

说了这么多,我们来看看他这是咋做到的
大概是这么个形状:(不是源码就长这样的意思嗷)

// (!) Approximate behaviorfunction useEvent(handler) {  const handlerRef = useRef(null);  // In a real implementation, this would run before layout effects  useLayoutEffect(() => {    handlerRef.current = handler;  });  return useCallback((...args) => {    // In a real implementation, this would throw if called during render    const fn = handlerRef.current;    return fn(...args);  }, []);}

先回顾几个Hook相关知识点:

useRef

useRef:

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内持续存在。

这里通过 useRef 保存回调函数handlerhandlerRef.current,然后再在 useCallback 中从handlerRef.current来取函数再调用,这样避免了直接调用,跳出了闭包陷阱。并且不出意外的话handler在整个生命周期内持续存在,也就是只有一个引用

useLayoutEffect

这个 useLayoutEffect 可能没那么常用,我们来看看这是啥嘞

其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

useEffect

回顾一下 useEffect

默认情况下,effect 将在每轮渲染结束后执行

两者的区别

好了,现在我给你用一个字总结一下两者区别,useLayoutEffect 更“快”!这个“块”不是速度更快,而是他“抢跑”了哩。useLayoutEffect 是在render之前同步执行,useEffectrender之后异步执行,这里就是保证useLayoutEffect 里的回调肯定比useEffect更早前被调用、被执行。

useCallback执行时机

前面说到

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

文档里是这样说 useMemo 的:

记住,传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行与渲染无关的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo。

也就是他是在render执行的,也就是保证了赋值handlerhandlerRef.current是在前面发生

这里的作用

这里返回的是一个useCallback包裹后 memoized函数,其中从handlerRef.current中获取函数,并且deps[],也就是说他不会再次更新。

感谢各位的阅读,以上就是“useEvent降低Hooks负担的原生Hook分析”的内容了,经过本文的学习后,相信大家对useEvent降低Hooks负担的原生Hook分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

useEvent降低Hooks负担的原生Hook分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

useEvent降低Hooks负担的原生Hook分析

这篇文章主要讲解了“useEvent降低Hooks负担的原生Hook分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“useEvent降低Hooks负担的原生Hook分析”吧!没有 useE
2023-07-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录