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

如何让暗黑模式切换组件重载页面时不触发过渡事件?

解决页面重载时暗黑模式过渡触发的问题

问题背景

我用React和MUI开发了一个暗黑模式切换组件,代码如下:

import { IconButton } from "@mui/material";
import React, { useState, useEffect } from "react";
import { Brightness4, Brightness7 } from "@mui/icons-material";

const ThemeChanger = () => {
  const [themeState, setThemeState] = useState(false);

  useEffect(() => {
    const getTheme = localStorage.getItem("Theme");
    if (getTheme === "dark") {
      setThemeState(true);
    }
  }, []);

  useEffect(() => {
    if (themeState) {
      localStorage.setItem("Theme", "dark");
      document.body.classList.add("dark-mode");
    } else {
      localStorage.setItem("Theme", "light");
      document.body.classList.remove("dark-mode");
    }
  }, [themeState]);

  return (
    <div>
      <IconButton
        className="icon-button"
        style={{ marginTop: "16px" }}
        onClick={() => {
          setThemeState(!themeState);
          document.body.classList.add("dark-light-toggle-transition");
        }}
      >
        {themeState ? <Brightness4 /> : <Brightness7 />}
      </IconButton>
    </div>
  );
};

export default ThemeChanger;

页面重载时,组件会触发dark-mode类的过渡动画。我试过用jQuery、window.performance方法,还尝试给body加preload类把transition设为none,但因为useEffect的执行逻辑,只要themeState为true就会添加dark-mode类,过渡还是会触发。

解决方案

核心思路是只在用户主动点击切换按钮时才启用过渡效果:

  1. 创建dark-light-toggle-transition类,在类中定义需要的过渡样式(比如transition: background-color 0.3s ease;)
  2. 仅在点击切换按钮的事件中给body添加这个过渡类;页面初始化/重载时不添加该类,这样设置dark-mode类就不会触发过渡

如果需要避免过渡类一直存在,还可以在点击后加个定时器移除它,保证仅在切换过程中生效:

onClick={() => {
  setThemeState(!themeState);
  document.body.classList.add("dark-light-toggle-transition");
  setTimeout(() => {
    document.body.classList.remove("dark-light-toggle-transition");
  }, 300); // 时长和过渡动画时长保持一致
}}

这样既保证了手动切换时有平滑过渡,页面重载时完全不会触发过渡效果。

内容的提问来源于stack exchange,提问作者Nikolaos G.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 06:36:27