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

如何在React中正确使用useEffect实现简易计数器逻辑?

问题分析与解决方案

原始代码的问题

第一版代码的问题

  • 重复绑定事件导致浏览器冻结:useEffect没设置依赖数组,组件每次渲染(包括count更新后)都会执行这段代码,给按钮重复添加点击事件监听。点击按钮时会触发多次旧的事件处理器,最终导致浏览器卡死。
  • 闭包导致标题显示不同步:countClick里的count是闭包捕获的组件渲染时的旧值,赋值document.title时用的是更新前的count,所以标题显示的数值比页面段落里的慢一步。

第二版代码的问题

  • 闭包捕获旧值:useCallback依赖数组为空,countClick里的count始终是初始值0,标题永远显示You clicked 0 times。
  • 添加依赖后的异常:把count加入useCallback依赖后,每次count变化都会生成新的countClick函数,useEffect会重新绑定事件,依旧可能出现重复绑定问题,且闭包导致的标题更新不及时问题也没解决。

最佳实现方案

React里完全不需要手动操作DOM绑定事件,直接用组件的onClick属性即可;标题更新通过监听count变化实现,更符合React声明式编程范式,代码简洁可靠:

const Counter = () => {
  const [count, setCount] = useState(0);

  // 监听count变化,自动更新页面标题
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  const handleClick = () => {
    // 用函数式更新确保基于最新值递增
    setCount(prevCount => prevCount + 1);
  };

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={handleClick}>
        Click me
      </button>
    </div>
  );
};

方案说明

  1. 使用React原生onClick事件:避免手动操作DOM绑定事件,从根源解决重复绑定问题,这是React处理事件的标准方式。
  2. 函数式更新count:prevCount => prevCount + 1的写法确保每次递增都是基于最新的count值,规避闭包带来的旧值问题。
  3. useEffect同步标题:当count变化时自动更新页面标题,保证标题和页面显示的count值完全同步。

内容的提问来源于stack exchange,提问作者aquile hollins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:25:27