React红绿灯组件问题:超时后颜色不切换且无法显示
React红绿灯组件问题修复:颜色不显示+状态不切换
问题1:类型不匹配导致函数报错
你定义的类型是type stopLightState = "stop" | "slow" | "go",但getStopLightClass函数的参数类型写的是StopLightState,TypeScript会识别为未定义类型,导致函数无法正确接收参数,类名生成逻辑失效。
问题2:模板字符串插值语法错误
生成类名时用了$(light),正确的ES6模板字符串插值应该是${light},这会导致类名变成无效的light $(light),而不是预期的light stop/light slow/light go,CSS样式无法匹配,信号灯颜色自然不显示。
问题3:状态切换逻辑缺失+死循环
- 当
state为"slow"时,你调用setState("slow"),会触发useEffect无限重复执行,因为状态每次被设置为相同值依然会触发依赖更新。 - 没有处理
"go"状态的切换逻辑,导致从"stop"切换到"go"后,状态就不再变化,缺少"go"→"slow"→"stop"的完整循环。
问题4:未清理定时器导致内存泄漏
useEffect中创建的定时器在组件卸载或状态更新时没有清理,可能触发不必要的状态更新,造成内存泄漏。
修正后的完整代码
import "./styles.css"; import { useState, useEffect } from "react"; // 统一类型命名,保持一致性 type StopLightState = "stop" | "slow" | "go"; const STOP_DELAY = 3000; const SLOW_DELAY = 2000; const GO_DELAY = 3000; // 补充go状态的延迟时间 export default function App() { const [state, setState] = useState<StopLightState>("stop"); // 修复类型参数与模板字符串语法 function getStopLightClass(light: StopLightState) { return `light ${light}${state === light ? " on" : ""}`; } useEffect(() => { let timer: NodeJS.Timeout; if (state === "stop") { timer = setTimeout(() => setState("go"), STOP_DELAY); } else if (state === "go") { timer = setTimeout(() => setState("slow"), GO_DELAY); } else if (state === "slow") { timer = setTimeout(() => setState("stop"), SLOW_DELAY); } // 清理定时器,避免内存泄漏 return () => clearTimeout(timer); }, [state]); return ( <div className="stopLight"> <div className={getStopLightClass("stop")}></div> <div className={getStopLightClass("slow")}></div> <div className={getStopLightClass("go")}></div> </div> ); }
额外说明
- 统一类型命名,确保参数类型与定义一致
- 修复模板字符串语法,让类名正确生成(例如
light stop on) - 补全完整状态循环:stop → go → slow → stop
- 添加定时器清理逻辑,避免内存泄漏
- 延迟常量改为大写命名(符合JS规范),移除无用的
here文本
内容的提问来源于stack exchange,提问作者Ram01
相关产品推荐
相关产品推荐

