我需要根据网站的当前部分稍微更改主题。
似乎MuiThemeProvider
仅在加载时设置muiTheme
;但是当道具改变时需要更新。
如何做到这一点?
答案 0 :(得分:3)
您可以尝试将主题放在一个包装组件中,以保持主题的状态。使用React's context此组件向子组件公开函数以更改状态。
import React, { Component } from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import PropTypes from 'prop-types';
import theme from './theme';
import themeOther from './theme-other'
class Wrapper extends Component {
static childContextTypes = {
changeTheme: PropTypes.func
};
constructor(props) {
super(props);
this.state = {
muiTheme: getMuiTheme(theme)
};
}
getChildContext() {
return {changeTheme: this.changeTheme};
}
changeTheme = () => {
this.setState({
muiTheme: getMuiTheme(themeOther)
})
};
render() {
return (
<MuiThemeProvider muiTheme={this.state.muiTheme}>
{this.props.children}
</MuiThemeProvider>
)
}
}
export default Wrapper;
在某些子组件中,您可以访问上下文并调用changeTheme函数以在状态中设置不同的主题。确保包含contextTypes,否则你无法访问该函数。
import React, { Component } from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import PropTypes from 'prop-types'
class ChildComponent extends Component {
static contextTypes = {
changeTheme: PropTypes.func
};
render() {
return (
<RaisedButton
primary
onTouchTap={this.context.changeTheme}
label="Change The Theme"
/>
);
}
}
export default ChildComponent;
在应用的根目录中,只需渲染包装器。
ReactDOM.render(
<Wrapper>
<App />
</Wrapper>,
document.getElementById('root')
);
修改强> 我的第一个解决方案可能已经过多了。因为您要替换整个应用程序的整个主题。您也可以像这样在树下使用MuiThemeProvider。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import inject from 'react-tap-event-plugin';
inject();
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import theme from './theme';
ReactDOM.render(
<MuiThemeProvider muiTheme={getMuiTheme(theme)}>
<App />
</MuiThemeProvider>,
document.getElementById('root')
);
在子组件中,您可以再次使用MuiThemeProvider并覆盖某些属性。请注意,这些更改将反映在此MuiThemeProvider中的所有子项。
import React, { Component } from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import theme from './theme';
import { green800, green900 } from 'material-ui/styles/colors';
const localTheme = getMuiTheme(Object.assign({}, theme, {
palette: {
primary1Color: green800,
primary2Color: green900
}
}));
class App extends Component {
render() {
return (
<div>
<RaisedButton
primary
label="Click"
/>
<MuiThemeProvider muiTheme={localTheme}>
<RaisedButton
primary
label="This button is now green"
/>
</MuiThemeProvider>
</div>
);
}
}
export default App;