简体   繁体   中英

React theme not applied to children components

This is my first interaction with React, the code is below:

header.jsx

import React from 'react';
import AppBar from 'material-ui/AppBar';
import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import FlatButton from 'material-ui/FlatButton';
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert';
import NavigationClose from 'material-ui/svg-icons/navigation/close';

class Header extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            logged: false
        };
    }

    render() {
        return (
            <AppBar title="Some title"
                iconElementLeft={<IconButton><NavigationClose /></IconButton>}
                iconElementRight={this.state.logged ? <Logged /> : <Login />} />
        );
    }
}

class Login extends React.Component {
    render() {
        return (
            <FlatButton label="Login" />
        );
    }
}

class Logged extends React.Component {
    render() {
        return (
            <IconMenu iconButtonElement={<IconButton><MoreVertIcon /></IconButton>}
                targetOrigin={{ horizontal: 'right', vertical: 'top' }}
                anchorOrigin={{ horizontal: 'right', vertical: 'top' }}>
                <MenuItem primaryText="Item1" />
                <MenuItem primaryText="Item2" />
                <MenuItem primaryText="Item2" />
            </IconMenu>
        );
    }
}

export default Header;


index.jsx

import React from 'react';
import ReactDOM from 'react-dom';

import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';

import Header from './header.jsx';

import injectTapEventPlugin from 'react-tap-event-plugin';

injectTapEventPlugin();

class App extends React.Component {
  render() {
    return (
      <MuiThemeProvider muiTheme={getMuiTheme(lightBaseTheme)}>
        <div>
          <Header />
          <p> Hello React!</p>
        </div>
      </MuiThemeProvider>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

The problem is that the theme is applied to the AppBar only and not to its components, that are and , this is what i got: 在此处输入图片说明

However, if I change the Header component by adding the code from component directly in the AppBar component, like this:

<AppBar title="Some title"
                iconElementLeft={<IconButton><NavigationClose /></IconButton>}
                iconElementRight={this.state.logged ? <Logged /> : <FlatButton label="Login" />} />

the result is different:

Could you please tell me what am I missing in order for the theme to be propagated to the child components and why does it work in the second scenario?

Thanks in advance!

在此处输入图片说明

AppBar internal implementation checking type of the element provided to iconElementRight property. Theme will be provided 'automatically' just of case of explicit match type to some predefined values, like FlatButton for your example.

Here is how this works internally (taken from material-ui/AppBar source code):

// around 239 line
if (iconElementRight) {
  var iconElementRightProps = {};

  switch (iconElementRight.type.muiName) {
    case 'IconMenu':
    case 'IconButton':
      var iconElemRightChildren = iconElementRight.props.children;
      var _iconButtonIconStyle = !(iconElemRightChildren && iconElemRightChildren.props && iconElemRightChildren.props.color) ? styles.iconButtonIconStyle : null;

      iconElementRightProps.iconStyle = (0, _simpleAssign2.default)({}, _iconButtonIconStyle, iconElementRight.props.iconStyle);
      break;

    case 'FlatButton':
      iconElementRightProps.style = (0, _simpleAssign2.default)({}, styles.flatButton, iconElementRight.props.style);
      break;

    default:
  }

As you can see, if you providing some custom component you need to apply styles to match theme manually, for example with context:

class Login extends React.Component {
  render() {
    return(
      <FlatButton style={{
        color: this.context.muiTheme.appBar.textColor
      }}/>
    )
  }
}

Login.contextTypes = {
  muiTheme: React.PropTypes.object.isRequired,
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM