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

React报错Too many re-renders:暗黑模式切换引发无限循环

解决React暗黑模式切换时的无限重渲染问题

错误原因

你写的onClick={pMode=== "light"? setPmode("dark") : setPmode("light")}是直接执行了setPmode函数,而非把一个函数传递给onClick。组件每次渲染时,这个三元表达式都会被计算,调用setPmode会触发组件重新渲染,重新渲染又会再次调用setPmode,形成无限循环,所以触发了Too many re-renders报错。

修复步骤

  1. 修改onClick事件,传递函数而非直接调用状态更新方法
    把onClick改成箭头函数,这样只有用户点击时才会执行状态更新逻辑:
onClick={() => setPmode(pMode === "light" ? "dark" : "light")}
  1. 同步父组件传入的Mode属性(可选但推荐)
    如果父组件的Mode属性可能发生变化,子组件的pMode需要同步更新,这时候要添加useEffect监听props.Mode:
useEffect(() => {
    setPmode(props.Mode);
}, [props.Mode]); // 当props.Mode变化时更新pMode
  1. 优化开关状态匹配(可选)
    给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:55:45