useEffect依赖项中的全局范围变量?
像‘window.location.pathname’这样的外部范围值不是有效的依赖项,因为改变它们不会重新渲染组件。 用例
假设我们必须在每个页面上执行一个操作,并且每当路由更改时我们都必须执行此操作。
由于我们必须在每个页面组件上执行操作,所以让我们将逻辑抽象为一个钩子。文件
index.js 文件包含具有两个页面的路由器配置 -> 主页和其他页面。
主页和其他页面仅呈现文本并调用公共 useLocation 挂钩。
在 useLocation 钩子中,我们将根据 window.location.pathname 执行一些操作,这是一个全局范围的变量。// FILENAME -> index.js import React from "react"; import { render } from "react-dom"; import { BrowserRouter as Router, Route, Link } from "react-router-dom"; import Other from "./components/Other"; import Home from "./components/Home"; // Basic Router to render Home Page and Other Page const BasicExample = () => (
); render(, document.getElementById("root"));// FILENAME -> useLocation.js // This is the hook that we will be running on each page import { useEffect } from "react"; const useLocation = (pathname) => { useEffect(() => { /* * If the pathname is same as current page path, perform some operation * For this example, the operation is to alert the user * only if pathname passed and window.location.pathname are equal */ if (pathname === window.location.pathname) { alert( `On Page -> , pathname -> ${pathname}, window.location.pathname -> ${window.location.pathname}` ); } }, [pathname, window.location.pathname]); }; export default useLocation;// Home Page import React from "react"; import useLocation from "../useLocation"; const Home = () => { useLocation("/"); return Home
; }; export default Home; // ---------------------------------------------------------------------- // Other Page import React from "react"; import useLocation from "../useLocation"; const Other = () => { useLocation("/other"); return Other
; }; export default Other;相互作用
在交互中,我们可以看到,一旦我们登陆主页,我们就会看到路径 -> "/" 的警告,然后导航到其他页面,我们会看到路径 -> "/other" 的警告。
一切似乎都很好,那么问题是什么? 问题
让我们修改代码以在效果运行完成后执行清理操作。
在修改后的代码中,我们会将警报作为清理操作的一部分。// FILENAME -> useLocation.js // This is the hook that we will be running on each page import { useEffect } from "react"; const useLocation = (pathname) => { useEffect(() => { /* * If the pathname is same as current page path, perform some operation * For this example, the operation is to alert the user * only if pathname passed and window.location.pathname are equal */ if (pathname === window.location.pathname) { // MODIFIED CODE HERE -> removed alert from this condition // doSomeOperation() } // MODIFIED CODE HERE -> CLEANUP OPERATION // Added the same alert here return () => { alert( `On Page -> , pathname -> ${pathname}, window.location.pathname -> ${window.location.pathname}` ); } }, [pathname, window.location.pathname]); }; export default useLocation;
现在让我们看看交互
当我们导航到其他页面时,主页效果已经完成运行并运行清理操作。
虽然我们希望路径和路径名相同,但在警报中我们有路径名 -> ‘/’ 和 window.location.pathname -> ‘/other’。
发生这种情况是因为 window.location.pathname 在清理操作开始时发生了变化。
当我们从其他页面导航回主页时,也会发生同样的事情。 解决方案
让我们修改代码以在依赖项中不使用 window.location.pathname ,而是使用钩子中定义的局部变量。// FILENAME -> useLocation.js // This is the hook that we will be running on each page import { useEffect } from "react"; const useLocation = (pathname) => { // MODIFIED CODE HERE -> Assigned path = window.location.pathname // Use this variable across the hook const path = window.location.pathname; useEffect(() => { /* * If the pathname is same as current page path, perform some operation * For this example, the operation is to alert the user * only if pathname passed and path are equal */ if (pathname === path) { // doSomeOperation() } return () => { alert( `On Page -> , pathname -> ${pathname}, window.location.pathname -> ${path}` // Use path instead of window.location.pathname ); } }, [pathname, path]); }; export default useLocation;
现在让我们看看交互
应用修复后,我们可以看到我们获得了正确且一致的值。
这是可行的,因为路径是每个hook实例的局部变量。 虽然它在初始化时被分配给 window.location.pathname,但只有在重新渲染时才会重新分配。
你遇到过这样的问题吗! 请在评论中让我知道!
攻略图鉴京津冀2小时旅游圈!春暖花开,说走就走万物复苏,春暖花开,又到了出门踏青的季节。周末两天,因时间仓促只能选择京内游?你out了!高铁1。5小时,你便可现身石家庄,夜游正定古城,眺望千年古城流光溢彩高铁2小时,你就能抵达
崩溃大陆图鉴第一世界工作台塑石器(第四个)甲盔甲铠甲套甲靴扁石锤六尺钉耙黄玉长剑灶盆化学台(第五工作台)眩目镜邮件君机器人(相当于无敌金身)石头动物床捕蝇网芦荟草盆栽太阳菇盆栽尖刺果盆栽石墙扁
大道至简,繁杂的只是人心心中有春天,花儿才会开放,胸中有大海,才能扬帆起航。人生中,处世要讲策略,做事要讲原则。眼睛能看到的地方,是视野,而思想能触及的地方,才叫格局。在生活中,我们会遇到各种人,有人表面
湖台两地旅游交流推介会在浙江湖州举行湖台两地旅游交流推介会在浙江湖州举行(图片来源湖州市台办)中国台湾网3月17日讯湖台两地旅游交流推介会今日在浙江湖州举行。本次活动以相向而行携手并进为主题,湖台两地旅游业界人士代表
观点张相木以大数据驱动探索新能源车质量安全,守住安全底线文懂车帝原创李德喆懂车帝原创行业3月19日,以智电新引擎蝶变新能源为主题的2023年中国新能源汽车大数据产业峰会在辽宁省沈阳市举行。新能源汽车国家大数据联盟理事长张相木在主论坛环节
65岁退休?韩国棋手81岁选择退休,日本96岁老棋手还能战胜对手!都说职业棋手捧着个金饭碗,此言不虚。因为在这里,根本就没有什么60岁退休和65岁退休的问题。日前,曾任韩国棋院首任事务总长的郑东植六段宣布退休。郑东植六段出生于1942年,全北大学
北京首发,直达莫斯科!3月16日9时许,一列满载汽车配件建材家电铜版纸布料服装家居等货物的中欧班列从北京平谷马坊站驶出。据介绍,该班列是从北京地区首发的中欧班列,共55个40英尺集装箱,将经由满洲里铁路
10绝杀保持不败,U24国足又爆发了,冲击亚运会,底线4强文彬少侃球(首发)3月份是亚洲足坛的比赛月份,国字号各阶段的比赛都集中在这段时间,其中U20亚洲杯持续进行,目前到了半决赛阶段,U20国足最终是止步了8强,未能打进4强可惜,这也导
妈妈走后每一位母亲和女儿都会在这本书中认出彼此今天我们的评审书目妈妈走后,来自韩裔美国作家米歇尔佐纳。妈妈走后讲述了一个关于母亲与女儿爱与悲伤食物与自我认同的成长故事。无法理解女儿的严厉母亲,无法满足母亲期待的叛逆女儿,在最后
缺失生命教育的孩子为什么如此脆弱?这本书揭开了残忍的真相电影遗愿清单中有这样一段话我们不能总是想着等到我以后有了钱,有了时间,或者什么其他条件成熟以后,再去做一些我们早就想做的事情,因为你永远不知道你是否能看到明天的太阳。当死神降临,谁
美国花400亿搬走台积电,暴露自身三大弱点,原来中国芯片也很强借助芯片研究技术的成熟,美国在很长一段时间里都是芯片生产大国,直到冷战结束后,开始了大规模的产业转移。在产业转移的背景下,美国大量企业开始转移到了东亚地区,其中就包括了香港,台湾以