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

按下Enter键修改状态触发React Too Many re-renders错误如何解决?

问题根因

你遇到的无限重渲染问题本质是闭包陷阱 + useEffect依赖配置错误,具体逻辑如下:

  1. 你在useEffect中绑定了键盘监听事件,但是依赖数组只填了index,onKeyPress函数内部用到的timerState没有被纳入依赖
  2. 这就导致你绑定的onKeyPress永远持有首次渲染时的闭包,里面的timerState永远是初始值false
  3. 每次你按下Enter键,都会命中if(timerState === false)的判断,调用setTimerState(true),触发组件重渲染
  4. 重渲染后新的onKeyPress函数里的timerState已经是true,但因为useEffect的依赖没有变化,不会重新绑定事件,旧的监听函数还在,后续每次按Enter都会重复触发setTimerState,最终触发React的重渲染次数限制报错。

修复方案

你可以按以下步骤修改代码:

  • 先引入useCallbackHook
  • 用useCallback包裹onKeyPress函数,把它用到的所有外部依赖(timerState、index、words)都加到useCallback的依赖数组里
  • 把包裹后的onKeyPress加到useEffect的依赖数组里,保证每次onKeyPress变化时都会重新绑定最新的事件监听
  • 可选优化:判断按键匹配时加边界判断,避免index超出words数组长度时报错

修改后的核心代码示例:

// 新增引入useCallback
import React, { useState, useEffect, useCallback } from 'react';

function App() {
  const [index, setIndex] = useState(0);
  const [showSignIn, setShowSignIn] = useState(false);
  const [timerState, setTimerState] = useState(false);

  // 用useCallback包裹onKeyPress,声明完整依赖
  const onKeyPress = useCallback((event) => {
    console.log("Current key: ", event.key);

    switch (event.key) {
            
      case "Enter":
        if(timerState === false){
          setTimerState(true);
        }
        break;

      case "Backspace":
        break;

      default:
        // 新增数组越界判断
        if(index < words.length && event.key === words[index]){
          setIndex((prev) => prev + 1);
        }
        break;
    }
  }, [timerState, index, words])

  const openSignIn = () => {
    setShowSignIn(prev => !prev);
  };

  // 替换useEffect的依赖为onKeyPress
  useEffect(() => {
    document.addEventListener('keydown', onKeyPress);

    return () => {
      document.removeEventListener('keydown', onKeyPress);
    };
  }, [onKeyPress])

  // 其余return代码保持不变
}

额外说明

如果你的项目开启了ESLint的React Hooks检查规则,它会自动提示你缺失的依赖项,能帮你避免这类闭包相关的问题。

内容的提问来源于stack exchange,提问作者Colin Harker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:45:07