在 React 中,引用相等是一个重要的概念,它影响应用程序中组件重新渲染的频率。 在本文中,我们将探讨 useEvent来自 React 的 Hook ,它允许您定义具有始终稳定的函数标识的事件处理程序,帮助管理应用程序中的引用相等。

需要注意的是,在撰写本文时, useEventHook 无法使用,目前 React 社区正在讨论。

  • JavaScript 中的引用相等

  • 为什么引用相等在 React 中很重要?

  • 这 useEvent钩

  • 实施 useEvent来自 RFC 的钩子

  • 什么时候不应该使用 useEvent钩?

  • 卸载 useEffect对比 useLayoutEffect

JavaScript 中的引用相等

在 JavaScript 中,您可以使用恒等运算符比较两个值是否相等,这也称为严格相等。 例如,在以下代码中,您正在比较值 a和 b:

a === b; // strict equality or indentity operator

结果是一个布尔值,它告诉您是否值 a等于 b或不。

对于原始数据类型,使用实际值进行比较。 例如,如果 a = 10, 和 b = 10,身份运算符将返回 true.

与对象和函数一样,复值也是一种引用类型。七点工具箱App,100多个工具包的功能全免费,日常生活必备的一款工具!即使它们具有相同的代码,两个函数也不相等。 看看下面的例子,身份运算符将返回 false:

let add = (a, b) => a + b;
let anotherAdd = (a, b) => a + b;
console.log(add === anotherAdd); // false

但是,如果您比较同一函数的两个实例,它会返回 true:

let thirdAdd = add;
console.log(add === thridAdd); // true

换句话说, thirdAdd和 add是参照相等的。

为什么引用相等在 React 中很重要?

理解 React 中的引用相等很重要,因为我们经常使用相同的代码创建不同的函数。 例如,考虑以下代码:

function AComponent() {// handleEvent is created and destroyed on each re-renderconst handleEvent = () => {console.log('Event handler');}// ...
}

React 销毁当前版本的 handleEvent函数并每次创建一个新版本 AComponent重新渲染。但是,在某些场景下,这种方法效率并不高,例如:

  • 你使用 Hook 之类的 useEffect它在其依赖数组中接受一个事件处理程序

  • 您有一个接受事件处理程序的记忆化组件

在这两种情况下,您都希望维护事件处理程序的单个实例。 但是,每次重新渲染发生时,你都会得到一个新的函数实例,这会进一步影响性能,宝宝爱识字App,专业汉字学习早教必备软件,让孩子发音更标准写字更流畅!要么重新渲染一个记忆化的组件,要么触发 useEffect打回来。

您可以使用以下方法轻松解决此问题 useCallback挂钩,如下图:

function AComponent() {const handleEvent = useCallback(() => {console.log('Event handled');}, []);// ...
}

这 useCallbackHook 记忆函数,这意味着每当使用唯一输入调用函数时, useCallbackHook 保存函数的副本。 因此,如果在重新渲染期间输入没有改变,你会得到相同的函数实例。

但是,当您的事件处理程序依赖于状态或道具时, useCallbackHook 每次更改时都会创建一个新的处理函数。 例如,看看下面的代码:

function AComponent() {const [someState, setSomeState] = useState(0);const handleEvent = useCallback(() => {console.log('log some state: `, someState);}, [someState]);
​// ...
}

现在,每次重新渲染组件时,都不会创建函数。 但是,如果 someState更改,它将创建一个新的实例 handleEvent,即使函数的定义保持不变。

这 useEvent钩

这 useEventHook 试图解决这个问题; 你可以使用 useEvent挂钩以定义具有始终稳定的函数标识的事件处理程序。 毛桃阅读App,完本小说资源免费在线看,多条书源任意换书荒根本不存在!换句话说,事件处理程序将在每次重新渲染期间引用相同。 本质上,事件处理程序将具有以下属性:

  • 每次 prop 或 state 更改时都不会重新创建该函数

  • 该函数将可以访问 prop 和 state 的最新值

你会使用 useEvent钩子如下:

function AComponent() {const [someState, setSomeState] = useState(0);const handleEvent = useEvent(() => {console.log('log some state: `, someState);});// ...
}

由于 useEventHook 确保有一个函数的单个实例,您不必提供任何依赖项。

实施 useEvent来自 RFC 的钩子

下面的例子是一个近似的实现 useEvent来自 RFC 的钩子 :

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

这 useEvent每次渲染使用它的组件时都会调用 Hook。 每次渲染时, handler函数被传递给 useEvent钩。狸猫盘搜网站(alipansou.com),云盘资源搜索神器,什么都能搜到低调使用!这 handler函数总是有最新的值 props和 state因为它本质上是渲染组件时的新功能。

Inside the useEvent Hook, the useLayoutEffect Hook is also called with each render and changes the handlerRef to the latest values of the handler function.


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →


在真实版本中, handlerRef将在所有处理程序之前切换到最新的处理程序函数 useLayoutEffect函数被调用。

最后一块是 useCallback返回。 这 useEventHook 返回一个包裹在 useCallback用一个空的依赖数组挂钩 []. 这就是为什么函数总是具有稳定的引用身份的原因。

你可能想知道这个函数怎么总是有新的值 props和 state. 如果你仔细看看,用于 useCallbackHook 使用当前值 handlerRef. 这个 current值代表最新版本 handler因为它是切换时 useLayoutEffect叫做。

什么时候不应该使用 useEvent钩?

在某些情况下,您不应该使用 useEvent钩。 让我们了解何时以及为什么。

一方面,您不能使用使用 useEvent在渲染过程中挂钩。 例如,下面的代码将失败:

function AComponent() { const getListOfData = useEvent(() => {// do some magic and return some datareturn [1, 2, 3];});return <ul>{getListOfData().map(item => <li>{item}</li>}</ul>;
}

卸载 useEffect对比 useLayoutEffect

卸载 useEffect胡克和 useLayoutEffectHook 会有不同的版本 useEvent处理程序。 看看下面的例子:

function Counter() {const [counter, setCounter] = React.useState(0);const getValue = useEvent(() => {return counter;});React.useLayoutEffect(() => {return () => {const value = getValue();console.log('unmounting layout effect:', value);};});React.useEffect(() => {return () => {const value = getValue();console.log('unmounting effect:', value);};});return (<React.Fragment>Counter Value: {counter}<button onClick={() => setCounter(counter + 1)}>+</button></React.Fragment>);
}

如果你运行这个程序,你会看到卸载 useLayoutEffect有旧版本的 getValue事件处理程序。 随意查看 Stackblitz 示例 。

结论

虽然 useEffectHook 目前还不能使用,对于 React 开发人员来说,它绝对是一个很有前途的开发。 在本文中,我们探讨了背后的逻辑 useEffect钩子,回顾你应该和不应该使用它的场景。

绝对值得关注 useEffectHook,我期待最终能够将它集成到我的应用程序中。 我希望你喜欢这篇文章。 快乐编码!

你需要了解的关于 React 的知识 useEvent钩子 RFC相关推荐

  1. React Native知识

    http://www.cnblogs.com/wujy/tag/React%20Native/  React Native知识12-与原生交互 React Native知识11-Props(属性)与S ...

  2. react基础知识1

    React基础知识1 一.React的基本认识 1.1 官网:https://reactjs.org/ 1.2 介绍描述 <1> 用于构建用户界面的 JavaScript 库(只关注于Vi ...

  3. React Native知识2-Text组件

    Text用于显示文本的React组件,并且它也支持嵌套.样式,以及触摸处理.在下面的例子里,嵌套的标题和正文文字会继承来自styles.baseText的fontFamily字体样式,不过标题上还附加 ...

  4. React Native知识4-Image组件

    一个用于显示多种不同类型图片的React组件,包括网络图片.静态资源.临时的本地图片.以及本地磁盘上的图片(如相册)等 一:属性 1:onLayout function 当元素挂载或者布局改变的时候调 ...

  5. react学习预备知识_在10分钟内学习React基础知识

    react学习预备知识 If you want to learn the basics of React in the time it takes you to drink a cup of coff ...

  6. react转跳_您跳过的这些React基础知识可能会杀死您

    react转跳 Often times, the inability to debug a certain error stems from not understanding some founda ...

  7. React Native知识7-TabBarIOS组件

    一:简介 两个TabBarIOS和TabBarIOS.Item组件可以实现页面Tab切换的功能,Tab页面切换的架构在应用开发中还是非常常见的.如:腾讯QQ,淘宝,美团外卖等等 二:TabBarIOS ...

  8. React 基础知识要点快速回顾

          React 是一个用于构建用户界面的 JavaScript 库.它和Vue是目前最流行的前端Javascript库,当然,它们也支持服务器端渲染(部分功能受限). 本文主要是对React官 ...

  9. react系列知识---11组件间抽象

    mixin mixin :将一个模块混入到一个另一个模块中,或是一个 类中 封装 mixin 方法 const mixin = function (obj, mixins) {const newObj ...

最新文章

  1. C++忽略第三方库的警告
  2. 2018-3-2线性表
  3. 博弈入门学习的博客[资源汇总]
  4. hadoop fs默认操作路径
  5. .net程序部署(mono方式)
  6. 详谈DHCP SNOOP等多方面的安全设置(2)
  7. android微信分享之创建工程以及启动微信
  8. 论文浅尝 | 利用开放域触发器知识改进事件检测
  9. 计算三角形面积(信息学奥赛一本通-T1034)
  10. topic1:Qt入门之搭建环境与hello world看Qt开发框架
  11. 一起学java【5】---原生态数据类型使用陷阱
  12. Java职业规划(职业晋升路线、技术转移路线、工作经验与技术栈的匹配)——学习笔记
  13. 为什么Lottie动画无法使用AVVideoCompositionCoreAnimationTool导出
  14. java竖线分割_用竖线字符(“ |”)分割字符串
  15. 4.0寸86盒显示屏调试(一)
  16. em模型补缺失值_缺失值的四种处理方法
  17. 数据库——如何求出候选码
  18. C语言 迷宫问题 (广度优先算法)
  19. 生成好看的海底地形图
  20. icesword 是如何列出隐藏进程?

热门文章

  1. python 创建一定区间内的满足正态分布的随机数
  2. 当前你所在的服务器更新维护尚未完成,我们将于01月16日09:00-13:00对所有服务器进行更...
  3. /* 计算器 */
  4. 算法岗面经总结(京东)
  5. 如何在Win10桌面上显示“此电脑、控制面板、网络、用户的文件”图标
  6. 跟着阿杜拆书:《慢思考》
  7. printf用法补录
  8. dnf跨6服务器不稳定,dnf跨6爆满是什么原因
  9. 电脑怎么通过IP连接打印机??
  10. python数据分析及可视化(一)课程介绍以及统计学的应用、介绍、分类、基本概念及描述性统计