You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React点击按钮递增计数并跳过3的倍数问题排查与解决

问题分析与解决

需求与问题现状

需求:实现默认从0开始,点击按钮递增计数,若当前计数的下一个值为3的倍数则跳过该值,直接显示下一个有效值,预期序列为0,1,2,4,5,7,8,10,11...

现有代码运行后实际序列为0,1,2,3,5,6,8,9...,未跳过3的倍数,反而跳过了3的倍数的下一个值,同时控制台打印的count总是滞后于UI显示的值。

问题原因

  1. 闭包捕获旧状态:React的useState状态更新是异步批量处理的,changeCounter函数形成闭包,每次渲染时捕获的是当前周期的旧count值,这导致控制台打印的永远是上一次的状态,看起来滞后。async/await、setTimeout无法解决这个闭包陷阱,因为它们无法改变闭包捕获的旧值。
  2. 逻辑判断方向错误:当前逻辑是判断当前count是否为3的倍数来决定增量,但需求是下一个值不能是3的倍数。比如当count=2时,下一个值是3(3的倍数),现有逻辑判断2%3!==0,执行setCount(3),导致UI显示3,违背预期。

修复方案

核心是基于下一个值判断是否需要跳过,同时使用函数式更新获取最新状态值,避免闭包陷阱。

修改后的代码如下:

import React, {useState} from "react";

export default function App() {
  const[count, setCount] = useState(0);

  const changeCounter = () => {
    // 函数式更新,c为当前最新状态值
    setCount(c => {
      let next = c + 1;
      // 若下一个值是3的倍数,直接加1跳过
      if (next % 3 === 0) {
        next += 1;
      }
      return next;
    });
  }

  return (
    <div className="App">
      <h1>Hello People</h1>
      <p>Count: {count}</p>
      <button onClick={changeCounter}>Click me!</button>
    </div>
  );
}

代码说明

  • 函数式更新:setCount(c => ...)中的c是React提供的当前最新状态值,彻底避免闭包捕获旧值的问题,确保每次判断都基于最新的count。
  • 逻辑调整:先计算下一个值next = c + 1,如果next是3的倍数则再加1跳过,保证UI显示的永远不是3的倍数,完全符合预期序列。

若需要打印最新的count值,可通过useEffect监听状态变化:

import React, {useState, useEffect} from "react";

export default function App() {
  const[count, setCount] = useState(0);

  useEffect(() => {
    console.log('当前count值:', count);
  }, [count]);

  const changeCounter = () => {
    setCount(c => {
      let next = c + 1;
      if (next % 3 === 0) {
        next += 1;
      }
      return next;
    });
  }

  return (
    <div className="App">
      <h1>Hello People</h1>
      <p>Count: {count}</p>
      <button onClick={changeCounter}>Click me!</button>
    </div>
  );
}

useEffect会在count更新后触发,打印的就是最新状态值,不会再出现滞后问题。


内容的提问来源于stack exchange,提问作者Rajat Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:39:53