MuiThemeProvider:如何针对不同的路线使用不同的主题?

时间:2017-05-11 20:00:56

标签: reactjs material-ui

我需要根据网站的当前部分稍微更改主题。

似乎MuiThemeProvider仅在加载时设置muiTheme;但是当道具改变时需要更新。

如何做到这一点?

1 个答案:

答案 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;