范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

七爪源码从新的React文档中查看useEventpolyfill

  今年夏天的一个好日子,React 传奇人物 Dan Abramov 为期待已久的 useEvent 钩子发布了一个 polyfill。 介意我们看看吗?
  一点上下文
  如果您最近没有关注"新闻",您可能错过了 useEvent 的 RFC。 长话短说,以下是 React 团队对此的评价:
  我们怀疑 useEvent 是 Hooks 编程模型中一个基本缺失的部分,它将提供正确的方法来修复过度触发效果,而不会出现像跳过依赖项这样容易出错的 hack。
  实际上,在引入 useEvent 之前,您可能很难编写某些效果,而不必忽略数组中的依赖关系或对所需行为做出妥协。
  以 RFC 中的这个例子为例。 目标是在用户访问页面时记录分析:function Page({ route, currentUser }) {   useEffect(() => {     logAnalytics("visit_page", route.url, currentUser.name);   }, [route.url, currentUser.name]);   // ... }
  当路由更改时,会记录一个带有路由 URL 和用户名的事件。 现在假设用户在"个人资料"页面上,她决定编辑她的姓名。 效果再次运行并记录一个新条目,这不是我们想要的。
  使用 useEvent,您可以从效果中提取事件: function Page({ route, currentUser }) {   //   Stable identity   const onVisit = useEvent(visitedUrl => {     logAnalytics("visit_page", visitedUrl, currentUser.name);   });    useEffect(() => {     onVisit(route.url);   }, [route.url]); //   Re-runs only on route change   // ... }
  日志分析现在是为了响应由路由更改触发的事件而完成的。
  事件处理程序 (onVisit) 是通过 useEvent 创建的,它返回一个稳定的函数。这意味着即使组件重新渲染,useEvent 返回的函数也将始终相同(相同的标识)。正因为如此,它不再需要作为依赖传递给 useEffect
  您可以在 RFC 本身中阅读有关 useEvent 的其他示例和很酷的内容,例如在使用站点包装事件。但在我写这篇文章时,useEvent 仍在进行中。所以在它发布之前,人们仍然会想知道从他们的依赖数组中省略依赖是否安全......
  ....或者他们可以开始使用 Dan Abramov 在新的 React 文档中发布的 shim
  一个shim 诞生了
  如果你真的没有关注"新闻",那么你可能错过了 React 团队今年一直忙于重写他们的文档网站的事实(如果你来自未来,这里是 2022 年)。
  它仍处于测试阶段,但已经比旧版本好得多。我希望所有文档都和这个一样好。我一直提到丹·阿布拉莫夫的原因是他是主要作者(国王万岁)。
  效果在这些新文档中有一个特殊的部分。可能是因为自 React 16.8 发布以来,包括我自己在内的人们一直在错误地使用它们(或过度使用它们)。或者可能是因为当人们注意到升级到 React 18 后,他们的 1,000 个效果开始在 StrictMode 下运行两次时,他们开始抱怨。
  因此,毫不奇怪,您会在新文档中找到多达 5 页专门介绍效果的页面!您还将详细了解 useEvent 如何将您从依赖地狱中拯救出来。但当你开始接触它时,你会偶然发现以下陷阱之一:
  幸运的是,在这个炎热的夏天的一个美好的一天,除了这个大的免责声明之外,没有太多解释,在示例和挑战中添加了一个 polyfill:import { useRef, useInsertionEffect, useCallback } from "react";  // The useEvent API has not yet been added to React, // so this is a temporary shim to make this sandbox work. // You"re not expected to write code like this yourself.  export function useEvent(fn) {   const ref = useRef(null);   useInsertionEffect(() => {     ref.current = fn;   }, [fn]);   return useCallback((...args) => {     const f = ref.current;     return f(...args);   }, []); }
  有趣的。 我不了解你,但我忍不住想看看 shim 里面的代码。 即使这只是一个临时的,我也不希望自己写! 你呢?
  我是这么想的。
  然后让我们从第 7 行开始,这里声明了 useEvent shim。 正如预期的那样,钩子在参数中接收一个名为 fn 的回调函数,就像 RFC 中的那样:export function useEvent(fn) {
  接下来,使用 useRef 声明一个引用,该引用最初包含"null"值(第 8 行): const ref = useRef(null);
  接下来是有趣的部分:参考 (ref) 是从效果中设置的,而不是在 fn 更改时运行(第 9-11 行):   useInsertionEffect(() => {     ref.current = fn;   }, [fn]);
  这不是任何一种效果:React 团队选择使用在 React 18 中引入的插入效果。
  如果你不知道,React 中有几种效果:普通效果(由 useEffect 触发)、布局效果(useLayoutEffect)和插入效果(useInsertionEffect)。
  它们中的每一个都在组件生命周期的不同阶段触发。 首先是插入效果(在应用 DOM 突变之前),然后是布局效果(在 DOM 更新之后),最后是普通效果(在组件完成渲染之后),import { useEffect, useInsertionEffect, useLayoutEffect } from "react"; import "./styles.css";  export default function App() {   useEffect(() => console.log("useEffect"), []);   useInsertionEffect(() => console.log("useInsertionEffect"), []);   useLayoutEffect(() => console.log("useLayoutEffect"));    const setRef = (e) => console.log("setRef");    return (     

Open the console to see in which order the various effects run{" "} ); }   您应该在控制台中看到以下输出:   > useInsertionEffect   > setRef   > useLayoutEffect   > useEffect   这与我们之前所说的一致。我们还可以看到,插入效果的触发时间与 React 设置引用的时间差不多,更重要的是,在布局效果之前。   RFC 中的详细设计规定:   在所有布局效果运行之前切换 [event] 处理程序的"当前"版本。这避免了用户态版本中存在的陷阱,即一个组件的效果可以观察到另一个组件状态的先前版本。不过,切换的确切时间是一个悬而未决的问题(在底部列出了其他悬而未决的问题)。   现在可以理解为什么将引用设置在插入效果而不是任何其他类型的效果上。在布局效果内或以后运行的代码期望调用更新的引用。所以需要先更新参考。   使用插入效果当然不是万无一失的。可以尝试在另一种插入效果中使用事件处理程序。在这种情况下,参考可能还不是最新的。这就是为什么 useEvent 不能在用户空间中安全实现的原因。 React 内部的未来实现将解决这个问题。   但让我们回到垫片。我再贴一次,这样更容易理解:import { useRef, useInsertionEffect, useCallback } from "react"; // The useEvent API has not yet been added to React, // so this is a temporary shim to make this sandbox work. // You"re not expected to write code like this yourself. export function useEvent(fn) { const ref = useRef(null); useInsertionEffect(() => { ref.current = fn; }, [fn]); return useCallback((...args) => { const f = ref.current; return f(...args); }, []); }   最后一部分涉及 useCallback 返回的函数(第 12-15 行): return useCallback((...args) => { const f = ref.current; return f(...args); }, []);   该回调没有任何依赖项 [](第 15 行),因此它只创建一次。因此,useCallback 总是返回相同的函数。正因为如此,垫片返回一个满足规范的稳定函数。   现在是回调本身。我们看到:   1.返回 useCallback((...args)=> {   它接受一个可变的参数列表(代码没有对处理程序接受的参数数量做出任何假设):   2.常量 f = 参考电流;   它访问 ref 的当前值,其中包含最新的 fn 函数(感谢效果行 10 中的代码):   3.返回 f(...args);   最后,它调用该函数,转发收到的参数   在这里,我们有一个始终保持最新的稳定事件处理程序!而且由于事件处理程序是稳定的,因此无论是否将其包含在效果的依赖数组中都没有关系:它永远不会导致效果再次自行运行。   但为什么它会起作用?   是的,我很确定每个人仍然不清楚为什么这确实有效。事件处理程序如何始终是"最新的"?最新,我不仅仅意味着它的引用是最新的,还意味着它可以在运行时访问"新"值。   让我们回到 RFC 中的示例:function Page({ route, currentUser }) { // Stable identity const onVisit = useEvent(visitedUrl => { logAnalytics("visit_page", visitedUrl, currentUser.name); }); useEffect(() => { onVisit(route.url); }, [route.url]); // Re-runs only on route change // ... }   为什么当效果调用 onVisit 时,currentUser.name 是最新的,即使我们没有在任何地方指定它作为依赖项?   好吧,每次组件渲染时,我们都会使用新的箭头函数visitedUrl => { ... }调用useEvent。该函数访问 currentUser.name,该名称在组件范围的上层定义。这就是我们所说的闭包。因此,该函数会在渲染组件时"捕获" currentUser.name 的值。   由于我们使用的是 React,我们知道组件会在其 props 更改时重新渲染。这就是为什么每次组件渲染时我们都有一个新的 up-date 函数,useEvent 负责将其存储在它的 ref 中。然后,每当调用事件处理程序 (onVisit) 时,代码都会调用存储在 ref 中的函数,该函数"捕获"组件中的最新值。   当您尝试用它们的值替换属性时,更容易理解:   第一次渲染   假设该组件是使用以下内容呈现的: Page({ route: { url: "/profile" }, currentUser: { name: "Dan" }, });   当它发生时,您可以想象使用一个函数调用 useEvent,其中 currentUser.name 被 Dan 替换: const onVisit = useEvent(visitedUrl => { logAnalytics("visit_page", visitedUrl, "Dan"); });   在这个表示中,visitedUrl => { logAnalytics("visit_page",visitedUrl,"Dan"); } 是存储在 useEvent 中的 ref 中的内容。   因此,当效果使用它所依赖的 route.url 调用 onVisit 时,实际上使用以下值调用 logAnalytics: logAnalytics("visit_page", "/profile", "Dan");   第二次渲染   现在想象一下,丹将他的名字改为"瑞克"(对不起丹)。 React 使用以下命令重新渲染组件: Page({ route: { url: "/profile" }, currentUser: { name: "Rick" }, });   再次调用 useEvent ,这次是用一个函数将 currentUser.name 替换为 Rick(更新后的值):const onVisit = useEvent(visitedUrl => { logAnalytics("visit_page", visitedUrl, "Rick"); });   useEvent 再次使用visitedUrl => { logAnalytics("visit_page",visitedUrl,"Rick"); }。   但是由于 route.url 没有改变,所以效果没有运行,因此 onVisit 也没有被调用。 不记录任何分析。   第三次渲染   然后,Dan Rick 导航到主页。 组件再次渲染:Page({ route: { url: "/home" }, currentUser: { name: "Rick" }, });   useEvent 再次调用了一个函数,其中 currentUser.name 被 Rick 替换:const onVisit = useEvent(visitedUrl => { logAnalytics("visit_page", visitedUrl, "Rick"); });   尽管 currentUser.name 的值与之前("Rick")相同,但传递给 useEvent 的函数严格来说仍然是一个新函数。 它们是不同的实例,因此它们具有不同的身份(如果我们将该函数与前一个渲染中的函数进行比较,Object.is 将返回 false)。 所以 useEvent 再次更新它的 ref。 我们不在乎! 开销可以忽略不计。   最后,效果再次运行,因为它的依赖关系(route.url)发生了变化。 这意味着这次使用 /home 调用 onVisit ,然后调用 logAnalytics :logAnalytics("visit_page", "/home", "Rick");   正如您所期望的那样!   附带说明一下,有趣的是,在此示例中,路由 URL 是作为参数传递给 onVisit 事件的,而不是直接在处理程序内部引用(就像我们对 currentUser.name 属性所做的那样)。 这是一个重要的区别,因为这意味着我们将在效果运行时记录路由 URL。 如果我们在事件处理程序中使用了 logAnalytics("visit_page", route.url, currentUser.name),我们将始终记录路由 URL 的最新值。   在这种特殊情况下,它没有太大区别,因为效果中的代码是同步的。 但如果 onVisit 已被调用以响应异步方法,则传递给函数的路由 URL 的值将是效果运行时的值,它可能不再是最新的 route.url。   如果您喜欢您阅读的内容,请随时关注我以获取更多信息!   关注七爪网,获取更多APP/小程序/网站源码资源!


涨价劝退年轻人!卫龙辣条去年少卖了4万吨,漯河首富刘卫平也焦虑本文来源时代财经作者王言辣条第一股卫龙(09985。HK)资本市场优等生的光环正在逐渐散去。3月24日,卫龙发布了2022年财报,报告期内,其实现营收46。32亿元,同比减少3。5漫谈陆晓娅的生死两相安陆晓娅是新闻人心理人教育人公益人。退休前曾担任中国青年报高级编辑。首届邹韬奋新闻奖获得者中国保护未成年人杰出公民。近年来关注老年问题与死亡教育,曾在北京师范大学开设影像中的生死学课大韩体育会会长韩国将派史上最大规模代表团征战杭州亚运会来源中国驻韩国大使馆3月23日,邢海明大使会见国际奥委会委员大韩体育会会长李起兴。邢海明表示,中韩是分不开的友好近邻,去年两国共同纪念了建交三十周年,中韩文化交流年顺利收官。随着疫突然火了一种新裙子露胯裙,回头率高还时髦,潮人都在穿想要把春天的时尚感全部纳入囊中,没有合适的单品作为基础,相信巧妇也难为无米之炊。对于单品的剖析和选择,我们需要参考春季穿搭的利落和大方,不管明艳还是朴素,任何服装的设计必定要让你产南航夏秋航季在湘每周航班量将达948班中国日报3月24日长沙讯3月26日起,中国民航将迎来夏秋航季。南航发布消息称,新航季将有序调整加密湖南出港客运航线航班,计划执行航线52条,通航点40个,周均航班量将达948班次。蔡振华麻烦!60后小弟东窗事发,曾败光足协5千万,遭控诉3大问题最近中国足坛掀起一股反腐行动,在这一段时间接二连三有各种足协高层落马。除了此前备受关注的陈戌源陈永亮留意的相关人员之外,就在最近王小平黄松相关部门的主要负责人,同样被曝光接受调查。媒体人王小平并非足协工作人员,只是兼职其真正身份是律师直播吧3月24日讯据媒体人袁野报道,其实王小平并非足协工作人员,而是律师事务所的律师。在中国足协纪律委员会主任王小平涉嫌严重违法正式官宣后,媒体人袁野透露了王小平真正的身份。袁野在德天空图赫尔将与拜仁签约至2025年,换帅工作已进行数周直播吧3月24日讯据德国天空体育消息,图赫尔与拜仁的签约年限已经确定,拜仁新帅将签下一份直至2025年的合约。德天空的消息称,拜仁将在当地时间今天晚些时候解雇纳格尔斯曼,并任命图赫太空血液不会滴落,女性宇航员来生理周期怎么办?居然不能上厕所根据理论太空中液体不会滴落,要是女性宇航员来生理周期怎么办?最遭罪的是还不能使用太空马桶!人类进入太空已有数十年,但太空探索的过程中,仍有许多未解决的问题,其中之一是太空中女性宇航电商直播APP开发解决方案电商直播APP是近年来兴起的一种新的购物方式,很多企业和商家都开始关注并投入到此领域的开发中。电商直播APP不仅仅提供了产品展示和销售,还将实时直播和社交元素加入其中,为用户创造了我国科学家实现量子纠错新突破!我国科学家实现量子纠错新突破在中国科学院院士俞大鹏带领下,南方科技大学深圳量子科学与工程研究院超导量子计算实验室助理研究员徐源课题组联合福州大学教授郑仕标清华大学副教授孙麓岩等组成
年内最大幅度!万华化学宣布降价11月30日,万华化学集团股份有限公司宣布下调2022年12月份中国地区MDI价格,其中中国地区聚合MDI挂牌价16800元吨(比11月份价格下调1000元吨)纯MDI挂牌价200惠民医疗保险晋康保上线由山西省医疗保障局中国银行保险监督管理委员会山西监管局联合指导的惠民健康型产品晋康保正式上线。主要承保单位是中国人寿保险股份有限公司山西省分公司中国人民财产保险股份有限公司山西省分十大券商12月金股纵览摘要十家券商所选12月金股中,地产链食品饮料以及大安全板块新增较多,且国央企的关注度较高。十大券商12月金股纵览兴业证券兴业证券12月金股偏向成长,新增派能科技新奥股份中航西飞中国医药生物行业研究与策略准备迎接医药板块戴维斯双击(报告出品方作者开源证券,蔡明子余汝意龙永茂)1展望2023医药慢牛行情或将至,抓住优质成长股布局机遇1。1医药板块近15年经历的三次牛市主要受政策影响近十五年,医药板块在国家政策突破1600万吨中蒙口岸甘其毛都过货量已超2020年水平记者从内蒙古巴彦淖尔市口岸管理办公室等部门获悉,今年1至11月份,作为中蒙重要货运通道的甘其毛都口岸过货量突破1600万吨,达1607。81万吨,已超过2020年过货量水平,成为中造车势力一体化压铸布局情况造车势力一体化压铸布局情况1。大众2021年底将在德国沃尔夫斯堡建立新工厂,该工厂预计将从2026年起开始生产首批Trinity纯电动汽车大众计划在Trinity项目中引入一体化压股价大幅下跌,触及五年最低的股票排行股票代码股票名称当前价格最高价格688733hr壹石通42。91109。10601568hr北元集团5。7712。76688553hr汇宇制药W18。5042。38601077hrGet技能嵌入式软件测试的10条秘诀在嵌入式软件开发过程中,花在测试和花在编码的时间比通常在31左右(实际上可能更多)。这个比例会随着工程师编程测试水平的提高而不断下降,但无论如何,软件测试都是嵌入式软件开发中至关重5G杀手级应用!国家级测速软件来了随着互联网和智能手机的飞速发展,网络对于人们的意义,堪比水对于鱼的意义。如今,用户对于网络质量的要求越来越高,但在上网的过程中,难免会遭受网络波动延迟等情况。这时大家可能会选择网络喜讯置富科技通过龙岗区2022年创新型中小企业认定2022年11月30日,深圳市龙岗区投资推广和企业服务中心发布公示,根据深圳市工业和信息化局优质中小企业梯度培育管理实施细则规定,经企业自评佐证材料审核抽查审计等程序后,包括置富科名单公布!西安3项入围记者获悉,2022中国体育旅游精品项目入选名单日前公布,西安浐灞国家湿地公园获评精品景区,一带一路中国跆拳道国际公开赛以及西安城墙国际马拉松赛获评精品赛事,其中一带一路中国跆拳道国