你能帮我动态更改 React Material UI 主题吗?
/image/cdbgS.jpg /image/qRxPm.jpg
我尝试通过单击按钮更改主题属性。如控制台所示,主题属性正在发生变化。但这种变化并没有反射(reflect)主题。
沙盒代码:https://codesandbox.io/s/30qwyk92kq
const themeChange = () => {
alert(theme);
theme.palette.type = "light";
console.log(theme);
};
ReactDOM.render(
<MuiThemeProvider theme={theme}>
<React.Fragment>
<CssBaseline />
<App changeTheme={themeChange} />
</React.Fragment>
</MuiThemeProvider>,
document.getElementById("app")
);
当我单击按钮时,主题必须更改为深色
最佳答案
我正在使用 styledComponents
、typescript
和 material-ui
。
首先我定义了我的主题:
// This is my dark theme: dark.ts
// I defined a light.ts too
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
export const darkTheme = createMuiTheme({
palette: {
type: 'dark', // Name of the theme
primary: {
main: '#152B38',
},
secondary: {
main: '#65C5C7',
},
contrastThreshold: 3,
tonalOffset: 0.2,
},
});
我定义了一个themeProvider
函数,在这个函数中我将material-ui的ThemeProvider
包装在React上下文中,以便能够轻松更改主题:
import React, { useState } from 'react';
import {ThemeProvider} from "@material-ui/core/styles/";
import { lightTheme } from "./light";
import { darkTheme } from "./dark";
const getThemeByName = (theme: string) => {
return themeMap[theme];
}
const themeMap: { [key: string]: any } = {
lightTheme,
darkTheme
};
export const ThemeContext = React.createContext(getThemeByName('darkTheme'));
const ThemeProvider1: React.FC = (props) => {
// State to hold the selected theme name
const [themeName, _setThemeName] = useState('darkTheme');
// Retrieve the theme object by theme name
const theme = getThemeByName(themeName);
return (
<ThemeContext.Provider value={_setThemeName}>
<ThemeProvider theme={theme}>{props.children}</ThemeProvider>
</ThemeContext.Provider>
);
}
export default ThemeProvider1;
现在我可以在我的组件中使用它,如下所示:
import React from 'react';
import styled from 'styled-components';
import useTheme from "@material-ui/core/styles/useTheme";
const MyCardHeader = styled.div`
width: 100%;
height: 40px;
background-color: ${props => props.theme.bgColor};
color: ${props => props.theme.txtColor};
display: flex;
align-items:center;
justify-content: center;
`;
export default function CardHeader(props: { title: React.ReactNode; }) {
const theme = {
bgColor: useTheme().palette.primary.main,
txtColor: useTheme().palette.primary.contrastText
};
return (
<MyCardHeader theme={theme}>
{props.title}
</MyCardHeader>
);
}
对于在主题之间进行更改:
import React, {useContext} from 'react';
import { ThemeContext} from './themes/themeProvider';
export default function Header() {
// Get the setter function from context
const setThemeName = useContext(ThemeContext);
return (
<header>
<button onClick={() => setThemeName('lightTheme')}>
light
</button>
<button onClick={() => setThemeName('darkTheme')}>
dark
</button>
</header>
);
}
关于reactjs - React Material UI 主题更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55846691/