概要
create-react-app + react-router + Material-UI でアプリの雛形っぽいものを作ってみる。
下の react-router のサンプルを Material-UI で装飾するイメージ。
https://reacttraining.com/react-router/examples/basic
環境
node
v7.5.0npm
4.1.2create-react-app
1.0.3
手順
アプリを生成して、必要な node-module をインストール。
create-react-app cra
cd cra
npm i --save react-tap-event-plugin # おまじない
npm i --save react-router-dom
npm i --save material-ui
2017/2/15 各モジュールのバージョンは以下のとおり。
package.json
{
"name": "cra",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-scripts": "0.9.0"
},
"dependencies": {
"material-ui": "^0.17.0",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-router-dom": "^4.0.0-beta.6",
"react-tap-event-plugin": "^2.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
public/index.html の body タグのデフォルトのマージンが Material-UI の AppBar と相性が悪いので、マージンを 0 にする。
public/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>React App</title>
</head>
<body style='margin: 0'>
<div id="root"></div>
</body>
</html>
MuiThemeProvider と Router の子要素は1つにしなくちゃいけないので、
MuiThemeProvider を index.js に Router を App.js に割り振ってみる。
逆でも大丈夫。 どっちかで両方やっても大丈夫。
src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import injectTapEventPlugin from 'react-tap-event-plugin'; // おまじない
injectTapEventPlugin(); // おまじない
import App from './App';
ReactDOM.render(
<MuiThemeProvider muiTheme={getMuiTheme()}>
<App />
</MuiThemeProvider>
, document.getElementById( 'root' )
);
src/App.js
import React, { Component } from 'react';
import { AppBar, Drawer, List, ListItem } from 'material-ui';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const
Contact = () => <h2>----------------------------------Contact</h2>;
const
About = () => <h2>----------------------------------About</h2>;
const
Home = () => <h2>----------------------------------Home</h2>;
const
Topic = ( { match } ) => <h3>{match.params.topicId}</h3>;
const
Topics = ( { match } ) => <div>
<h2>Topics</h2>
<List>
<ListItem containerElement={ <Link to={`${match.url}/rendering`} /> } primaryText='Rendering with React' />
<ListItem containerElement={ <Link to={`${match.url}/components`} /> } primaryText='Components' />
<ListItem containerElement={ <Link to={`${match.url}/props-v-state`} /> } primaryText='Props v. State' />
</List>
<Route path={`${match.url}/:topicId`} component={Topic}/>
<Route exact path={match.url} render={ () => <h3>Please select a topic.</h3> } />
</div>;
export default class
App extends Component {
componentWillMount() {
this.setState( { drawerOpen: false } );
}
handleOpen = () => { this.setState( { drawerOpen: true } ); };
handleClose = () => { this.setState( { drawerOpen: false } ); };
render() {
return <Router>
<div>
<Drawer
docked={ false }
open={ this.state.drawerOpen }
containerStyle={ { top: 64 } }
onRequestChange={ this.handleClose }
>
<List>
<ListItem
primaryText='Item 1'
nestedItems={
[ <ListItem
key='0'
primaryText="Contact"
containerElement={<Link to="/contact" />}
onTouchTap={ this.handleClose }
/>
, <ListItem
key='1'
primaryText="About"
containerElement={<Link to="/about" />}
onTouchTap={ this.handleClose }
/>
]
}
/>
<ListItem
primaryText='Item 2'
nestedItems={
[ <ListItem
key='0'
primaryText="Home"
containerElement={<Link to="/" />}
onTouchTap={ this.handleClose }
/>
, <ListItem
key='1'
primaryText="topics"
containerElement={<Link to="/topics" />}
onTouchTap={ this.handleClose }
/>
]
}
/>
<ListItem
primaryText='Item 3'
nestedItems={
[ <ListItem key='0' value="V3-1" primaryText="T3-1" onTouchTap={ this.handleClose } />
, <ListItem key='1' value="V3-2" primaryText="T3-2" onTouchTap={ this.handleClose } />
]
}
/>
</List>
</Drawer>
<AppBar
title="CRA"
onLeftIconButtonTouchTap={ this.handleOpen }
/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/contact" component={Contact}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>;
}
}
実行
おなじみの
npm start
したら、ブラウザで localhost:3000 にアクセス。