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

Material UI页面间主题持久化问题及解决方案

MUI 5.14.1 主题持久化报错:theme.transitions.create is not a function 解决方案

在使用MUI 5.14.1时,若直接将主题实例存入localStorage以实现跨页面主题持久化,读取后作为useState初始值会触发theme.transitions.create is not a function错误。这是因为localStorage仅能存储可序列化的数据,直接存储主题实例会丢失其原型链上的方法(比如transitions.create)。

以下是两种可行的解决方案:

方案一:React Context 全局主题状态管理

通过Context在全局维护主题状态,仅存储主题的标识参数(如模式)而非完整实例,动态生成主题以保证方法完整性。

完整代码示例

// theme-context.js
import { createContext, useContext, useState, useMemo } from 'react';
import { createTheme } from '@mui/material/styles';

const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  // 从localStorage读取主题模式
  const [themeMode, setThemeMode] = useState(() => {
    return localStorage.getItem('themeMode') || 'light';
  });

  // 根据模式动态创建主题实例
  const theme = useMemo(() => {
    return createTheme({
      palette: {
        mode: themeMode,
      },
    });
  }, [themeMode]);

  const toggleTheme = () => {
    const newMode = themeMode === 'light' ? 'dark' : 'light';
    setThemeMode(newMode);
    localStorage.setItem('themeMode', newMode);
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export const useThemeContext = () => useContext(ThemeContext);

在App中引入使用:

// App.jsx
import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider, useThemeContext } from './theme-context';

function AppContent() {
  const { theme, toggleTheme } = useThemeContext();
  return (
    <MuiThemeProvider theme={theme}>
      <CssBaseline />
      <button onClick={toggleTheme}>切换主题</button>
      {/* 其他业务组件 */}
    </MuiThemeProvider>
  );
}

export default function App() {
  return (
    <ThemeProvider>
      <AppContent />
    </ThemeProvider>
  );
}

方案二:优化localStorage存储逻辑

不存储完整主题实例,仅存储主题的可序列化配置参数,读取后用这些参数重新创建主题实例,确保方法不丢失。

完整代码示例

import { useState, useMemo } from 'react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';

function App() {
  // 从localStorage读取主题配置
  const [themeConfig, setThemeConfig] = useState(() => {
    const saved = localStorage.getItem('themeConfig');
    return saved ? JSON.parse(saved) : { palette: { mode: 'light' } };
  });

  // 基于配置生成主题实例
  const theme = useMemo(() => createTheme(themeConfig), [themeConfig]);

  const toggleTheme = () => {
    const newMode = themeConfig.palette.mode === 'light' ? 'dark' : 'light';
    const newConfig = { ...themeConfig, palette: { mode: newMode } };
    setThemeConfig(newConfig);
    localStorage.setItem('themeConfig', JSON.stringify(newConfig));
  };

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <button onClick={toggleTheme}>切换主题</button>
      {/* 其他业务组件 */}
    </ThemeProvider>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:21:17