Material ui 如何从商店获取主题并在react admin上切换应用程序主题?

Material ui 如何从商店获取主题并在react admin上切换应用程序主题?,material-ui,react-admin,theming,themeprovider,Material Ui,React Admin,Theming,Themeprovider,react管理版本:3.8.4 我有一个react管理应用程序,我正在尝试在明暗主题之间切换 下面您可以看到Theme.js,在这里我导出了两个具有默认主题覆盖的对象,如文档中所述。() 正如您在下面看到的,我还创建了一个名为ThemeReducer.js的customReducer import { createMuiTheme } from '@material-ui/core/styles'; import { darkTheme } from '../../layout/Theme'

react管理版本:3.8.4

我有一个react管理应用程序,我正在尝试在明暗主题之间切换

下面您可以看到Theme.js,在这里我导出了两个具有默认主题覆盖的对象,如文档中所述。()

正如您在下面看到的,我还创建了一个名为ThemeReducer.js的customReducer

import { createMuiTheme } from '@material-ui/core/styles';

import { darkTheme } from '../../layout/Theme'
const Theme = createMuiTheme(darkTheme)

export default (previousState = Theme, action) => {
  if (action.type === 'SWITCH_THEME') {
    return action.theme;
  }
  return previousState;
}
const MyLayout = (props) => {
    const theme = useSelector(state => state.theme)
    return (
        <ThemeProvider theme={theme}>
            <Layout
                {...props}
                appBar={AppBar}
                sidebar={Sidebar}
                menu={Menu}
                notification={Notification}
            />
        </ThemeProvider>
    )
};
...
    import Layout from './layout'
    
    const App = () => {
    
      return (
        <div className="admin-body">
    
          <Admin
            customReducers={{ theme: Theme }}
            layout={Layout}
            authProvider={login}
            dataProvider={dataProvider}
            loginPage={LoginPage}
            locale="pt"
            customRoutes={[
              <Route
                key="configuration"
                path="/configuration"
                title="Configurações"
                component={Configuration}
              />
            ]}
          >
...
还有一个动作(ThemeAction.js)来分派状态:

要设置自定义减速机,如文档中所述,我在
属性上设置自定义减速机,如下所示:

import Theme from './store/reducers/themeReducer'


const App = () => {

  return (
    <div className="admin-body">

      <Admin
        customReducers={{ theme: Theme }}
        layout={Layout}
        authProvider={login}
        dataProvider={dataProvider}
        loginPage={LoginPage}
        locale="pt"
        customRoutes={[
          <Route
            key="configuration"
            path="/configuration"
            title="Configurações"
            component={Configuration}
          />
        ]}
      > ...
从“./store/reducers/themeReducer”导入主题
常量应用=()=>{
返回(
...
要在主题之间切换并设置到应用商店,我将使用此配置页面:

import React from 'react'
import { useSelector, useDispatch } from 'react-redux';
import Button from '@material-ui/core/Button';
import { switchTheme } from '../../store/actions/themeAction';
import { darkTheme, lightTheme } from '../../layout/Theme'
import { createMuiTheme } from '@material-ui/core/styles';

import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import { Title } from 'react-admin';

import './styles.css'

const Configuration = () => {
  const dispatch = useDispatch();
  const theme = useSelector(state => state.theme);

  const mainClass = 'configPage'

  return (
    <Card>
      <Title title="Configurações" />
      <CardContent className={mainClass}>
        <div className="theme-label">
          <p className="text" >Selecione seu Tema: </p>
          <Button
            variant="contained"
            className={theme.palette.type === 'light' ? 'active' : ''}
            onClick={() => dispatch(switchTheme(createMuiTheme(lightTheme)))}
          >
            Claro
        </Button>
          <Button
            variant="contained"
            className={theme.palette.type === 'dark' ? 'active' : ''}
            onClick={() => dispatch(switchTheme(createMuiTheme(darkTheme)))}
          >
            Escuro
        </Button>
        </div>
      </CardContent>
    </Card>

  )
}

export default Configuration;
从“React”导入React
从“react-redux”导入{useSelector,useDispatch};
从“@material ui/core/Button”导入按钮;
从“../../store/actions/themeAction”导入{switchTheme};
从“../../layout/Theme”导入{darkTheme,lightTheme}
从'@material ui/core/styles'导入{createMuiTheme};
从“@material ui/core/Card”导入卡片;
从“@material ui/core/CardContent”导入CardContent;
从“react admin”导入{Title};
导入“./styles.css”
常量配置=()=>{
const dispatch=usedpatch();
constTheme=useSelector(state=>state.theme);
const mainClass='configPage'
返回(
Selecione seu Tema:

调度(switchTheme(CreateMuiteme(lightTheme)))} > 克拉罗 调度(switchTheme(createMuiTheme(暗色)))} > 埃斯库罗 ) } 导出默认配置;
所有这些结构都运行良好,我的意思是全局状态主题正在正确更新,因此reducer正在获取单击的主题并切换状态

问题是,如文档中所述,要更改默认主题,我们必须将新主题作为标记
上的属性传递,例如:
但是标签
被设置到App.js中,并且redux上下文不在App的上方,因此无法将全局主题状态放入其中

然后我的问题是如何使用我创建的全局主题状态作为应用程序主题传递

正如您在下面看到的,我已经尝试过作为布局的父级传递,但是主题没有反映在应用程序中

Layout.js

import { createMuiTheme } from '@material-ui/core/styles';

import { darkTheme } from '../../layout/Theme'
const Theme = createMuiTheme(darkTheme)

export default (previousState = Theme, action) => {
  if (action.type === 'SWITCH_THEME') {
    return action.theme;
  }
  return previousState;
}
const MyLayout = (props) => {
    const theme = useSelector(state => state.theme)
    return (
        <ThemeProvider theme={theme}>
            <Layout
                {...props}
                appBar={AppBar}
                sidebar={Sidebar}
                menu={Menu}
                notification={Notification}
            />
        </ThemeProvider>
    )
};
...
    import Layout from './layout'
    
    const App = () => {
    
      return (
        <div className="admin-body">
    
          <Admin
            customReducers={{ theme: Theme }}
            layout={Layout}
            authProvider={login}
            dataProvider={dataProvider}
            loginPage={LoginPage}
            locale="pt"
            customRoutes={[
              <Route
                key="configuration"
                path="/configuration"
                title="Configurações"
                component={Configuration}
              />
            ]}
          >
...
constmylayout=(道具)=>{
constTheme=useSelector(state=>state.theme)
返回(
)
};
App.js

import { createMuiTheme } from '@material-ui/core/styles';

import { darkTheme } from '../../layout/Theme'
const Theme = createMuiTheme(darkTheme)

export default (previousState = Theme, action) => {
  if (action.type === 'SWITCH_THEME') {
    return action.theme;
  }
  return previousState;
}
const MyLayout = (props) => {
    const theme = useSelector(state => state.theme)
    return (
        <ThemeProvider theme={theme}>
            <Layout
                {...props}
                appBar={AppBar}
                sidebar={Sidebar}
                menu={Menu}
                notification={Notification}
            />
        </ThemeProvider>
    )
};
...
    import Layout from './layout'
    
    const App = () => {
    
      return (
        <div className="admin-body">
    
          <Admin
            customReducers={{ theme: Theme }}
            layout={Layout}
            authProvider={login}
            dataProvider={dataProvider}
            loginPage={LoginPage}
            locale="pt"
            customRoutes={[
              <Route
                key="configuration"
                path="/configuration"
                title="Configurações"
                component={Configuration}
              />
            ]}
          >
...
。。。
从“./Layout”导入布局
常量应用=()=>{
返回(
...
谢谢你的帮助。
关于

我不知道您的要求,但可能没有必要在redux中存储主题?您可以使用使用react上下文api的解决方案,如下所示:

type themstate={
主题:“光”|“暗”,
setTheme(主题:“亮”|“暗”):void,
};
const StateContext=React.createContext({
主题:"光",,
setTheme:()=>{}
});
export const ThemeStateProvider=(道具:{children:React.ReactNode})=>{
const[theme,setTheme]=React.useState('light');
返回(
{props.children}
);
};
export const useThemeState=()=>useContext(StateContext);
然后像这样使用它:

//包装应用程序的新根组件
常量根=()=>(
)
const-App=()=>{
const{theme}=usethemstate();
回来
}
const配置=()=>{
const{setTheme}=usethemstate();
[...]
返回(
[...]
setTheme('light')}/>
[...]
);
}

希望对您有用!

这是一个更简单的解决方案,我现在没有想到。谢谢您的帮助,它工作得很好!太棒了。谢谢。