如何向Material UI中createTheme生成的主题对象传递参数
解决方案
1. 改造theme.js为动态生成函数
将原来的静态主题对象改为导出一个接收参数的函数,你可以传入任意自定义参数控制主题配置:
import { createTheme, responsiveFontSizes } from '@material-ui/core' // 改为接收参数的函数,支持传入darkMode等自定义配置 const createAppTheme = (darkMode = false) => { return createTheme({ palette: { mode: darkMode ? 'dark' : 'light', primary: { main: '#777777' }, secondary: { main: '#333333' }, medGray: { main: "#999999" }, navBar: { main: darkMode ? '#1a1a1a' : '#ffffff' // 也可以用darkMode控制其他配置项 }, }, components: { MuiButton: { defaultProps: { variant: "contained", }, styleOverrides: { root: { borderRadius: '2rem' } } }, MuiOutlinedInput: { defaultProps: { inputProps: { } }, styleOverrides: { root: { marginBottom: '1rem', borderRadius: '2rem', border: 'none', ":before": { border: 'none' } }, } } } }) } export default (darkMode) => responsiveFontSizes(createAppTheme(darkMode))
2. 存储darkMode全局状态
在你的Redux状态切片(比如现有userState或者新建themeState)中添加darkMode字段,默认值可设为false,同时新增切换主题的action即可。
3. 修改ContextWrapper动态生成主题
从Redux中获取darkMode状态,调用主题生成函数生成对应主题后传入ThemeProvider,配合useMemo避免不必要的重复渲染:
import { ThemeProvider } from '@material-ui/core' import { useMemo } from 'react' import createAppTheme from '../styles/theme' // 导入改为导入生成函数 import { useDispatch, useSelector } from 'react-redux' import { useEffect } from 'react' import userActions from '../store/actions/userActions' import { useRouter } from 'next/router' const ContextWrapper:React.FC = ({children: children}) => { const { loggedIn, darkMode } = useSelector((state: any) => state.userState) // 新增获取darkMode const dispatch = useDispatch() const router = useRouter() useEffect(() => { const user = window.sessionStorage.getItem('user_object') if (user) { dispatch({ type: userActions.LOG_IN, payload: JSON.parse(user) }) } else if (router.pathname != '/signup-test') { router.push('/signup-test') } }, [loggedIn]) // 仅当darkMode变化时重新生成主题 const theme = useMemo(() => createAppTheme(darkMode), [darkMode]) return( <ThemeProvider theme={theme}> {children} </ThemeProvider> ) } export default ContextWrapper
后续需要切换明暗主题时,只需要dispatch修改Redux中darkMode字段的action,主题就会自动全局更新。
内容的提问来源于stack exchange,提问作者Joel Hager
相关产品推荐
相关产品推荐

