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

如何将React明暗模式逻辑迁移至Context文件?

迁移明暗模式至React Context的解决方法

1. 新建ThemeContext及Provider组件

把明暗模式的状态逻辑全部迁移到Context的Provider中,同时将状态和更新方法暴露给子组件:

// src/contexts/ThemeContext.js
import { createContext, useContext, useState, useEffect } from 'react';

const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [lightMode, setLightMode] = useState(false);

  // 从本地存储读取用户偏好
  useEffect(() => {
    const storedPreference = localStorage.getItem('prefersLightMode');
    try {
      if (storedPreference) {
        setLightMode(JSON.parse(storedPreference));
      } else {
        const prefersLightMode = window.matchMedia('(prefers-color-scheme: light)').matches;
        setLightMode(prefersLightMode);
      }
    } catch (error) {
      console.log(error);
    }
  }, []);

  // 更新本地存储和body类名
  useEffect(() => {
    try {
      localStorage.setItem('prefersLightMode', JSON.stringify(lightMode));
      lightMode ? document.body.classList.add('light') : document.body.classList.remove('light');
    } catch (error) {
      console.log(error);
    }
  }, [lightMode]);

  // 封装切换方法(也可直接暴露setLightMode,按需选择)
  const toggleLightMode = () => setLightMode(prev => !prev);

  return (
    <ThemeContext.Provider value={{ lightMode, toggleLightMode, setLightMode }}>
      {children}
    </ThemeContext.Provider>
  );
}

// 自定义Hook,简化组件调用
export function useTheme() {
  return useContext(ThemeContext);
}

2. 在根组件中包裹Provider

确保整个应用能访问到ThemeContext的状态:

// src/App.jsx
import { ThemeProvider } from './contexts/ThemeContext';
import ToggleComponent from './components/ToggleComponent';

function App() {
  return (
    <ThemeProvider>
      {/* 其他业务组件 */}
      <ToggleComponent />
    </ThemeProvider>
  );
}

export default App;

3. 修改开关组件,通过Context获取状态和方法

替换原来直接使用的lightMode和setLightMode,改用Context提供的属性:

// src/components/ToggleComponent.jsx
import { useTheme } from '../contexts/ThemeContext';

function ToggleComponent() {
  const { lightMode, toggleLightMode } = useTheme();

  return (
    <div className="form-control">
      <label className="label cursor-pointer">
        <span className="label-text">明暗模式切换</span>
        <input
          type="checkbox"
          className="toggle toggle-primary"
          checked={lightMode} // 绑定checked属性,确保UI与状态同步
          onChange={toggleLightMode}
        />
      </label>
    </div>
  );
}

export default ToggleComponent;

错误原因分析

出现'setLightMode is not a function'的常见情况:

  • 组件未被ThemeProvider包裹,导致useContext获取到默认空值
  • Context的value对象中未正确包含setLightMode方法
  • 解构时出现大小写错误,比如写成setlightMode

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:31:49