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

React中setState引发函数重复执行及无限渲染问题求助

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

问题根源

你直接在组件函数体内调用setDark(localDark),每次组件渲染时这段代码都会执行,而setDark会触发组件重新渲染,于是陷入「渲染→调用setDark→重新渲染→再次调用setDark」的无限循环,最终触发React的渲染次数限制报错。

修正方案

1. 用函数式初始值初始化状态

把useState的初始值改成从localStorage读取的函数,这样只会在组件第一次初始化时执行一次读取操作,不会每次渲染都触发:

const [dark, setDark] = useState(() => {
  const savedDark = localStorage.getItem("dark");
  return savedDark !== null ? JSON.parse(savedDark) : false;
});

2. 优化点击事件逻辑

原来的点击事件里,localStorage.setItem存的是修改前的状态值,用setDark的回调形式可以确保拿到最新状态,同时同步localStorage和body类名:

const onClick = () => {
  setDark(prevDark => {
    const newDark = !prevDark;
    localStorage.setItem("dark", newDark);
    // 用toggle简化类名操作
    document.body.classList.toggle("dark", newDark);
    return newDark;
  });
};

3. 移除组件内的if判断代码

删掉原来那个直接调用setDark的if代码块,因为初始状态已经通过useState的函数式参数处理了localStorage的读取。

4. 用useEffect同步body类名(可选但推荐)

如果页面刷新或外部修改localStorage时,确保body类名和状态一致,添加useEffect监听状态变化:

useEffect(() => {
  document.body.classList.toggle("dark", dark);
}, [dark]);

完整修正代码

import { useState, useEffect } from 'react';

function Mode() {
  const [dark, setDark] = useState(() => {
    const savedDark = localStorage.getItem("dark");
    return savedDark !== null ? JSON.parse(savedDark) : false;
  });

  const onClick = () => {
    setDark(prevDark => {
      const newDark = !prevDark;
      localStorage.setItem("dark", newDark);
      return newDark;
    });
  };

  useEffect(() => {
    document.body.classList.toggle("dark", dark);
  }, [dark]);

  return (
    <div onClick={onClick} className="mode">
      {dark ? <Light /> : <Dark />}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:16:08