【发布时间】:2020-09-18 18:33:39
【问题描述】:
react-admin 版本:3.8.4
我有一个 react-admin 应用,我正在尝试在浅色和深色主题之间切换。
您可以在下面看到 Theme.js,我在其中导出了两个具有默认主题覆盖的对象,如文档中所述。 (https://material-ui.com/pt/customization/default-theme/)
export const darkTheme = {
palette: {
type: 'dark'
},
overrides: {
MuiAppBar: {
colorSecondary: {
backgroundColor: '#424242', //'#1e4c9a',
color: '#fff'
},
},
MuiButton: {
textPrimary: {
color: '#fff',
}
},
MuiTypography: {
colorPrimary: {
color: '#fff'
}
},
MuiDrawer: {
paper: {
paddingTop: '20px'
}
},
MuiFilledInput: {
underline: {
'&:after': {
borderBottomColor: '#bf9f00'
}
}
},
MuiFormLabel: {
root: {
'&$focused': {
color: '#bf9f00'
}
}
},
}
}
export const lightTheme = {
palette: {
type: 'light'
},
overrides: {
MuiAppBar: {
colorSecondary: {
backgroundColor: '#2196f3',
color: '#fff'
},
},
},
}
我还做了一个 customReducer,如下所示,名为 ThemeReducer.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;
}
还有一个动作来调度状态(ThemeAction.js):
export const switchTheme = (theme) => {
return {
type: 'SWITCH_THEME',
theme
}
}
要设置自定义 Reducer,如文档中所述,我在 <Admin> 上设置了自定义 Reducer 属性,如下所示:
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}
/>
]}
> ...
要在主题之间切换并设置到我正在使用此配置页面的商店:
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;
所有这些结构都工作正常,我的意思是全局状态主题正在正确更新,因此reducer 正在获取点击的主题并切换状态。
问题在于,如文档中所述,要更改默认主题,我们必须将新主题作为标签 <Admin> 上的属性传递,例如:<Admin theme={theme}> </admin>
但是标签<Admin>是在App.js中设置的,redux上下文不在App之上,所以无法获取全局主题状态。
那么我的问题是如何使用我创建的全局主题状态作为应用程序主题传递。
如下所示,我已经尝试将其作为 Layout 的父级传递,但主题并未反映在应用程序上。
Layout.js
const MyLayout = (props) => {
const theme = useSelector(state => state.theme)
return (
<ThemeProvider theme={theme}>
<Layout
{...props}
appBar={AppBar}
sidebar={Sidebar}
menu={Menu}
notification={Notification}
/>
</ThemeProvider>
)
};
App.js
...
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}
/>
]}
>
...
感谢任何帮助。 问候
【问题讨论】:
标签: material-ui react-admin theming themeprovider