更新后的状态值不会在反应函数内部更新

2023-12-21

反应状态更新值显示在使用效果中,但内部函数仅显示旧值。

const [counter, setCounter] = useState(0);

我正在尝试更新设定间隔函数内的计数器值

 const handleIncrease = () => {
clearInterval(intervalval);
if (counter < 10) {
  let increment = setInterval(() => {
    console.log("isCounterContinue@handleIncrease", counter);
    setCounter((prev) => prev + 1);
  }, 1000);
  setIntervalval(increment);
}

}; useEffect 内部显示更新后的值。但函数内部handleIncrease只显示旧值 基本上,我试图让计数器值在超过 30 时不增加。

代码链接:https://codesandbox.io/s/bold-cdn-zzbs2?file=/src/App.js https://codesandbox.io/s/bold-cdn-zzbs2?file=/src/App.js


handleIncrease仅在单击按钮时调用,并具有当前状态。单击处理程序中没有任何需要更新的内容。我认为您真正想要的是访问更新的counter间隔回调中的状态,每秒“滴答”一次。或者更准确地说,响应isCounterContinue状态切换 false 以在达到限制时停止间隔。

使用 ref 来保存对间隔计时器的引用,并使用它来设置/清除,而不是在外壳中陈旧的状态。

const Timer = () => {
  const [counter, setCounter] = useState(0);
  const intervalRef = useRef();

  useEffect(() => {
    console.log({ counter });
    if (counter >= 5) {
      clearInterval(intervalRef.current);
    }
  }, [counter]);

  const handleIncrease = () => {
    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setCounter((prev) => prev + 1);
    }, 1000);
  };

  const handleDecrease = () => {
    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setCounter((prev) => prev - 1);
    }, 1000);
  };

  const handleStop = () => {
    clearInterval(intervalRef.current);
  };

  return (
    <>
      <div>{counter}</div>
      <div>
        <button onClick={handleDecrease}>Decrease</button>
        <button onClick={handleStop}>Stop</button>
        <button onClick={handleIncrease}>Increase</button>
      </div>
    </>
  );
};

建议

除了添加到计数中的内容之外,增量/减量处理程序基本相同。使用柯里化函数通过关闭递增值来处理这两种情况。由于“停止”处理程序共享清除间隔的逻辑,因此请使用以下事实:0是一个假值,并且仅重新启动真值(即非零)数值的间隔计时器,并对所有三个按钮使用一个处理程序。

const handleIncrease = (val) => () => {
  clearInterval(intervalRef.current);
  if (val) {
    intervalRef.current = setInterval(() => {
      setCounter((prev) => prev + val);
    }, 1000);
  }
};

...

<button onClick={handleIncrease(-1)}>Decrease</button>
<button onClick={handleIncrease(0)}>Stop</button>
<button onClick={handleIncrease(1)}>Increase</button>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更新后的状态值不会在反应函数内部更新 的相关文章

随机推荐

  • Firebase sendPasswordResetEmail 在 React 中不起作用

    我尝试使用 firebase 创建网络应用程序的密码重置选项 其他 firebase 选项工作正常 例如 GoogleLogin 和电子邮件注册 但是当我尝试时sendPasswordResetEmail它返回以下错误 类型错误 fireb
  • 最好的 Python GIS 库? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Laravel Passport - 测试密码授予

    我使用 Laravel 5 7 和 Passport 为第一方客户端创建 API 我有一个登录表单 它接受用户的电子邮件和密码并将两者发送到自定义 LoginController 然后 LoginController 创建一个 oAuth
  • NSPredicate 不适用于字典数组

    我有一个 NSPredicate 其格式如下 Status CONTAINS cd shipped 我有一个字典数组 这是一个例子 Category Category 4 Comp Category 4 Depth 02 Grade New
  • 具有空间数据的 3D 交互式曲面图

    我想创建一个湖泊深度的交互式 3D 表面图 最好使用plotly or rgl图书馆 我已经从一个中提取了我的数据SpatialLinesDataFrameGauss Krueger EPSG 31468 CRS 中的等高线 即公制单位 现
  • 2010 年 .NET Compact Framework 是否更新?

    这个问题 net 紧凑框架 4 0 https stackoverflow com questions 245566 net compact framework 4 0 在VS 2010发布之前就问过这个问题 答案基本上都是说等待发布 现在
  • 请求的资源node.js上不存在Access-Control-Allow-Origin标头[重复]

    这个问题在这里已经有答案了 我在尝试通过 ajax 请求与我的 node js 服务器通信时遇到问题 我已经这样配置我的服务器 var allowCrossDomain function req res next res header Ac
  • 无法从 xml 定义中找到 Activity 中的 onClick 方法

    我试图将一个函数链接到 AndroidStudio 中按钮的 onClick 属性 但由于某种原因 系统无法识别我编码的方法 有趣的是 当我用 Java 编写代码时 它可以正常工作 在 Kotlin 中则不然 我更新了 Kotlin 并检查
  • ul 左侧​​的浮动图像忽略边距/填充

    我有一个段落 后面是一个无序列表 其中有几个列表项 我还有一个图像浮动在其左侧 我遇到的问题是列表项边距 填充与该图像重叠 我希望图像旁边的项目符号按应有的方式缩进 这是一个测试 http testing gorocketfuel com
  • 包含 std::string 的 memset 结构

    我有一个庞大的结构 其中整个内容是标量变量 枚举和标量数组 基于堆栈 但一个 std string 变量除外 现在 这是我的问题 我可以将结构的整个大小设置为 0 就像我会的那样 如果它只是所有标量 或者 std string 在那里是不可
  • 速记类构造函数字段初始化

    我忍不住觉得有一种简写方法可以写成这样 public abstract class MessageBase public String Destination Sender Uid public MessageBase String des
  • 在 F# 中实现受限数字类型的习惯用法/实践?

    假设需要一种数值数据类型 其允许的值落在指定范围内 更具体地说 假设要定义一个最小值为 0 最大值为 5000 的整数类型 这种情况在很多情况下都会出现 例如在对数据库数据类型 XSD 数据类型等进行建模时 在 F 中对此类类型进行建模的最
  • android 在将数据插入数据库之前检查重复值

    String new recorded lastname a lastname record to database Cursor cursor db rawQuery SELECT lastname FROM people null if
  • 如何在 C 中一次清除多个位?

    我如何将所有这些简化为一行 REG BITA REG BITB REG BITC REG BITD REG BITE 您可以使用 按位或 运算符 REG BITA BITB BITC BITD BITE
  • 如何从 Map> 创建 Multimap

    我没有找到这样的多重映射构造 当我想这样做时 我会迭代映射 并填充多重映射 还有其他办法吗 final Map
  • NSOutlineView 组间距

    我正在开发 NSOutlineView SourceList 并希望用我自己的样式替换当前样式 以便更好地查看我的应用程序 我已经使用自定义 NSTableViewRows 更改了默认标题和内容单元格 这很好用 但现在我可以看到组之间有一个
  • 在 WebView 中禁用邮寄地址的自动链接

    android WebView 将自动检测 html 中的邮寄地址 并允许您单击它来启动地图 有没有办法在不更改本机代码的情况下禁用此功能 我可以在 html 标记中添加一些内容或取消 javascript 事件来防止这种情况发生吗 如果我
  • Angular 6 / 在 tsconfig.lib.json 中声明库的路径

    我正在尝试配置路径Angular 6库 我已经成功配置了以前的 Angular 项目的路径 这是我以前的应用程序的工作原理tsconfig json file compilerOptions baseUrl src paths class
  • 变量多态性的初始化

    假设您有以下代码 class A int i 4 A print void print System out println A class B extends A int i 2 this line public static void
  • 更新后的状态值不会在反应函数内部更新

    反应状态更新值显示在使用效果中 但内部函数仅显示旧值 const counter setCounter useState 0 我正在尝试更新设定间隔函数内的计数器值 const handleIncrease gt clearInterval