React报错Too many re-renders:暗黑模式切换引发无限循环
解决React暗黑模式切换时的无限重渲染问题
错误原因
你写的onClick={pMode=== "light"? setPmode("dark") : setPmode("light")}是直接执行了setPmode函数,而非把一个函数传递给onClick。组件每次渲染时,这个三元表达式都会被计算,调用setPmode会触发组件重新渲染,重新渲染又会再次调用setPmode,形成无限循环,所以触发了Too many re-renders报错。
修复步骤
- 修改onClick事件,传递函数而非直接调用状态更新方法
把onClick改成箭头函数,这样只有用户点击时才会执行状态更新逻辑:
onClick={() => setPmode(pMode === "light" ? "dark" : "light")}
- 同步父组件传入的Mode属性(可选但推荐)
如果父组件的Mode属性可能发生变化,子组件的pMode需要同步更新,这时候要添加useEffect监听props.Mode:
useEffect(() => { setPmode(props.Mode); }, [props.Mode]); // 当props.Mode变化时更新pMode
- 优化开关状态匹配(可选)
给input添加checked属性,让开关的选中状态和当前模式对应,提升用户体验:
checked={pMode === "dark"}
修复后的完整代码
import React, { useState, useEffect } from 'react'; export default function Navbar(props) { let [pMode, setPmode] = useState(props.Mode); // 同步父组件传入的Mode useEffect(() => { setPmode(props.Mode); }, [props.Mode]); return ( <> <nav className={`navbar navbar-expand-lg navbar-${pMode} bg-${pMode}`}> <div className="container-fluid"> <a className="navbar-brand" href="/">Navbar</a> <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> <div className="collapse navbar-collapse " id="navbarNav"> <ul className="navbar-nav mx-auto"> <li className="nav-item"> <a className="nav-link active" aria-current="page" href="/">Home</a> </li> <li className="nav-item"> <a className="nav-link" href="/">Features</a> </li> <li className="nav-item"> <a className="nav-link" href="/">Pricing</a> </li> </ul> <div className="form-check form-switch"> <input className="form-check-input" onClick={() => setPmode(pMode === "light" ? "dark" : "light")} type="checkbox" role="switch" id="flexSwitchCheckDefault" checked={pMode === "dark"} /> <label className="form-check-label" htmlFor="flexSwitchCheckDefault">{pMode} mode</label> </div> </div> </div> </nav> </> ); }
内容的提问来源于stack exchange,提问作者meruvu likith
相关产品推荐
相关产品推荐

