这是我与React的第一次互动,代码如下:
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'));
问题是主题仅应用于AppBar,而不是应用于其组件,这就是我所得到的:
但是,如果我通过直接在AppBar组件中添加组件中的代码来更改Header组件,如下所示:
<AppBar title="Some title"
iconElementLeft={<IconButton><NavigationClose /></IconButton>}
iconElementRight={this.state.logged ? <Logged /> : <FlatButton label="Login" />} />
结果不同:
请您告诉我,为了将主题传播到子组件以及为什么它在第二种情况下有效,我缺少了什么?
提前致谢!
答案 0 :(得分:0)
AppBar内部实现检查提供给iconElementRight
属性的元素的类型。主题将自动提供&#39;只是显式匹配类型与某些预定义值的情况,例如 FlatButton 。
以下是内部工作原理(取自material-ui / AppBar源代码):
// 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:
}
如您所见,如果您提供一些自定义组件,则需要手动应用样式以匹配主题,例如使用上下文:
class Login extends React.Component {
render() {
return(
<FlatButton style={{
color: this.context.muiTheme.appBar.textColor
}}/>
)
}
}
Login.contextTypes = {
muiTheme: React.PropTypes.object.isRequired,
};