今天在工作中遇到一个react hooks问题,虽然解决了但是对于其中的原因不太理解,这里发出来和大家一起讨论一下。
具体代码如下,场景步骤如下:
看了一些批量更新的知识,好像解释不了这种现象。大家有什么看法吗?
import { useCallback, useEffect, useState } from "react";export default function MyApp() { const [isPolling, setIsPolling] = useState(false); const [pollingCount, setPollingCount] = useState(0); const [timer, setTimer] = useState(); const handleClick = () => { cancle(); running(); }; useEffect(() => { if (isPolling && pollingCount <= 3) { console.log("33"); clearTimeout(timer); setTimer( setTimeout(() => { console.log("44"); running(); }, 1000) ); } }, [isPolling, pollingCount]); const running = useCallback(() => { console.log("running11:", isPolling, pollingCount); if (!isPolling) { console.log("11"); setIsPolling(true); } else if (isPolling) { console.log("22"); setPollingCount(pollingCount + 1); } }, [isPolling, pollingCount]); const cancle = () => { setIsPolling(false); setPollingCount(0); }; return ( <div> <div onClick={handleClick}>点击</div> </div> );}
执行结果如下
const running = useCallback(() => { setIsPolling((currentIsPolling) => { console.log("running11:", currentIsPolling, pollingCount); if (!currentIsPolling) { console.log("11"); return true; } else { console.log("22"); setPollingCount(pollingCount + 1); return currentIsPolling; // return current value without change } });}, [pollingCount]);
其实这个问题很基础,甚至还不涉及到任何框架,这里我用最简单的模型来简化一下你这个问题
const [isPolling, setIsPolling] = useState(true);const handleClick = () => { setIsPolling(false) console.log(isPolling); // true};
isPolling
是一个常量,在同一个作用域内,无论使用什么方式,都不可能实现后续去改变它的值,这就回答了你的疑问,为什么调用 setIsPolling(false)
后,isPolling
的值还是 true
其实每次更新 useState
定义的状态,都会驱动 函数组件
重新执行,在重新执行的作用域中,isPolling
的值才是更新后的值,
那么在更新之前的上一次作用域中如何确保拿到更新后的值呢,React也提供了相应的方式,使用 setter
的回调
setIsPolling((prevIsPolling) => { console.log(isPolling); // false})
React内部会在组件对应的 fiber
结构上维护一个更新队列,对于同一个状态连续的 setState 调用会形成一个循环链表,将上一次 setState 的结果传递给下一个 setState 的回调,因此通过回调的方式你能拿到上一次 setIsPolling
的新值
问题内容: 为什么不自动生成?我在应用程序服务器上遇到了一个问题,该服务器显然正在缓存一个旧类。 问题答案: 不会自动生成serialversionuid,因为它很危险。设置serialversionuid时,表示类的两个版本在序列化方面兼容。 假设您有一个名为Foo的类,并且它 没有serialversionuid (默认值),并且将Foo的实例序列化为文件。稍后,您将一些新成员添加到Foo类。
https://play.tailwindcss.com/sNnjkZnGWF?file=config 项目里配置了变体 为什么 当button 通过tab 获取焦点的时候 红色边框border_always样式没有生效?
为什么我使用shardingjdbc配置分表但是没有生效呢,是使用jpa的save方法进行插入的,是这个的问题吗,有大佬知道问题吗 我数据库中有yd_order表和yd_order_1和yd_order_2表想将插入yd_order表中的数据分表插入到这两个表中,配置应该是没问题的,就是完全没有走这个配置
问题内容: 我正在尝试做这样的事情: 不幸的是,即使在Java 9中也不存在。 为什么它被遗漏了? 建议的解决方法是什么? 问题答案: 为什么它被遗漏了? 该API提供了可重用的构建块。这里的相关积木是,,。通过这些,您可以实现所需的功能:将流内映射到对象,然后获得平面图。提供构建基块的排列是不切实际的,并且很难扩展。 建议的解决方法是什么? 如前所述,使用可用的构建基块(+ ):
许多编译器都提供128位整数类型,但我使用过的编译器都没有提供typedefs。为什么? 据我回忆,标准 用于此目的的储量 鼓励提供此类类型的实现提供typedef 要求此类实现提供至少128位的intmax_t (而且,我不相信我使用了实际上符合最后一点的实现)
直截了当的问题是,似乎无法在用户完成表单后指向的视图中显示我的viewBag值。 请指教...谢谢 我的索引操作结果简单返回模型数据。 my Get Edit”action result,只是使用相同的模型数据作为索引。 My Post"Edit"ActionResult,将新值(如果有)分配给模型并重定向到Index页面,但Index页面不显示ViewBag值?? 在我的索引视图中。。。