即时更改material-ui主题 - >不影响儿童

时间:2016-04-07 08:58:55

标签: reactjs redux material-ui

我正在使用react / redux-application,我正在使用material-ui。

我正在使用上下文(根据文档)在我的 CoreLayout-component (我的顶层组件)中设置主题。这在初始加载时按预期工作。

我希望能够在运行时切换主题。当我选择一个新主题时,我的redux商店会更新,因此会触发我的组件进行更新。问题是我的CoreLayout组件的子项不会受到影响 - 这是第一次!如果我反复更改我的主题(使用发送redux-action onChange的选择列表),则会更新子项。如果子组件在我的项目层次结构中位于2层,则会在2次操作调用后更新 - 因此上下文的传递方式存在一些问题。

我的CoreLayout.js组件

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import ThemeManager from 'material-ui/lib/styles/theme-manager';

const mapStateToProps = (state) => ({
    uiStatus: state.uiStatus
});

export class CoreLayout extends React.Component {
    getChildContext() {
        return {
            muiTheme: ThemeManager.getMuiTheme(this.props.uiStatus.get("applicationTheme").toJS())
        };
    }

    render () {
        return (
            <div className='page-container'>
                { this.props.children }
            </div>
        );
    }
}

CoreLayout.propTypes = {
   children: PropTypes.element
};

CoreLayout.childContextTypes = {
    muiTheme: PropTypes.object
};

export default connect(mapStateToProps)(CoreLayout);

我的一个子组件(LeftNavigation.js)

import React from "react";
import { connect } from 'react-redux';


import { List, ListItem } from 'material-ui';

const mapStateToProps = (state) => ({
    uiStatus: state.uiStatus
});

export class LeftNavigation extends React.Component {
    render () {

        return (
            <div className="left-pane-navigation">
                <List subheader="My Subheader" >
                    <ListItem primaryText="Search" />
                    <ListItem primaryText="Performance Load" />
                </List>
            </div>
        );
    }
}

LeftNavigation.contextTypes = {
    muiTheme: React.PropTypes.object
};

export default connect(mapStateToProps)(LeftNavigation);

我可以通过this.context.muiTheme访问上下文中的主题。 我可以通过在每个子组件中使用另一个getChildContext()实例来获取组件来更新主题,但是我会有很多组件,我非常希望避免这样做。

当我更改主题并且所有子组件按预期重新呈现时,将调用我的CoreLayout组件的getChildContext方法。

有什么想法吗?

更新:它在移动设备(至少iOS)上按预期工作

1 个答案:

答案 0 :(得分:0)

您可以使用muiThemeProvider来避免将getChildContext添加到任何子组件,提供程序会为您执行此操作。

...

import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import MyAwesomeReactComponent from './MyAwesomeReactComponent';

const App = () => (
 <MuiThemeProvider muiTheme={getMuiTheme()}>
    <MyAwesomeReactComponent />
 </MuiThemeProvider>
)

...

documentation中的更多信息。