React Material:UI Cookbook
上QQ阅读APP看书,第一时间看更新

How to do it...

Let's assume that your app renders AppBar components on several screens. Each AppBar component also renders Menu and title to the left, as well as Button to the right. Here's how you can implement your own AppBar component so that it's easier to use on several screens:

import React, { Fragment, Component } from 'react';

import { withStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';

const styles = theme => ({
root: {
flexGrow: 1
},
flex: {
flex: 1
},
menuButton: {
marginLeft: -12,
marginRight: 20
},
toolbarMargin: theme.mixins.toolbar
});

const MyToolbar = withStyles(styles)(
class extends Component {
static defaultProps = {
MenuItems: ({ closeMenu }) => (
<Fragment>
<MenuItem onClick={closeMenu}>Profile</MenuItem>
<MenuItem onClick={closeMenu}>My account</MenuItem>
<MenuItem onClick={closeMenu}>Logout</MenuItem>
</Fragment>
),
RightButton: () => <Button color="inherit">Login</Button>
};

state = { anchor: null };

closeMenu = () => this.setState({ anchor: null });

render() {
const { classes, title, MenuItems, RightButton } = this.props;

return (
<Fragment>
<AppBar>
<Toolbar>
<IconButton
className={classes.menuButton}
color="inherit"
aria-label="Menu"
onClick={e =>
this.setState({ anchor: e.currentTarget })
}
>
<MenuIcon />
</IconButton>
<Menu
anchorEl={this.state.anchor}
open={Boolean(this.state.anchor)}
onClose={this.closeMenu}
>
<MenuItems closeMenu={this.closeMenu} />
</Menu>
<Typography
variant="title"
color="inherit"
className={classes.flex}
>
{title}
</Typography>
<RightButton />
</Toolbar>
</AppBar>
<div className={classes.toolbarMargin} />
</Fragment>
);
}
}
);

const ToolbarAbstraction = withStyles(styles)(
({ classes, ...props }) => (
<div className={classes.root}>
<MyToolbar {...props} />
</div>
)
);

export default ToolbarAbstraction;

Here's what the resulting toolbar looks like:

And here's what the menu looks like when the user clicks on the menu button beside the title: