やったこと
Reactの初期画面の状態からMaterial-UIとreact-routerによるルーティングを実装する
開発環境
DockerでRuby on Rails + Reactを別々にアプリ作成する環境構築手順
実装手順
各種モジュールのインストール
Materai-UI、react-router、react-reduxなどアプリ開発で使うモジュールをインストールします。
(今回使わないものも含みます)
package.json
{
"name": "app_name",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@loadable/component": "^5.10.3",
"@material-ui/core": "^4.6.1",
"@material-ui/icons": "^4.5.1",
"@material-ui/styles": "^4.6.0",
"axios": "^0.19.0",
"connected-react-router": "^6.6.0",
"lodash": "^4.17.15",
"material-table": "^1.54.2",
"material-ui": "^0.20.2",
"material-ui-flat-pagination": "^4.0.0",
"normalize.css": "^8.0.1",
"prop-types": "^15.7.2",
"query-string": "^6.9.0",
"react": "^16.12.0",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^16.12.0",
"react-infinite-scroll-component": "^5.0.4",
"react-redux": "^5.0.4",
"react-router-dom": "^4.2.2",
"react-router-redux": "^5.0.0-alpha.9",
"react-scripts": "3.3.0",
"react-share": "^3.0.1",
"react-spring": "^8.0.27",
"react-swipe-card-chsstm": "^0.1.5",
"react-swipeable-views": "^0.13.3",
"react-with-gesture": "^4.0.8",
"recharts": "^2.0.0-beta.1",
"redux": "^4.0.4",
"redux-form": "^8.2.6",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"styled-components": "^4.4.1",
"vec-la": "^1.5.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
$ npm install
Reactの仕組み
- サイトとしてはpublic/index.htmlが表示される
-
<div id=”root”></div>
の部分がsrc/index.jsによりレンダリングされる -
<App/>
はsrc/App.jsから出力されたもの
react-router
Reactでルーティングを行うライブラリです。
ルーティングを一言でいうと、パスと出力したい内容を結ぶことです。
XXX.com/Homeにアクセスしたら、Home.jsの内容を表示する。
XXX.com/Infoにアクセスしたら、Info.jsの内容を表示する。みたいな...
Material-UI
Googleが言っている「マテリアルデザイン」を簡単にReactに実装できるようにしたパッケージ
今回作るもの
/
/term
/info
- /,/home,/infoでルーティングする
- Material-UIを導入し、スタイリングを行う
src/index.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { MuiThemeProvider } from '@material-ui/core/styles';
import { theme } from './materialui/theme'
import { BrowserRouter as Router } from 'react-router-dom';
ReactDOM.render(
<MuiThemeProvider theme={theme}>
<Router>
<App />
</Router>
</MuiThemeProvider>
, document.getElementById('root'));
- MUIThemeProviderタグで囲むことで、MaterialUIを適用している。theme={theme}の記述は、./materialui/theme.jsに記載したテーマカラーのカスタムを適用している
- Routerタグで、Routingを実現している
materiaiui/theme.js
theme.js
import { createMuiTheme } from '@material-ui/core/styles'
export const theme = createMuiTheme({ // #1
palette: {
primary: {
light: '#484848',
main: '#212121',
dark: '#000000',
contrastText: '#ffffff',
},
secondary: {
light: '#ffffff',
main: '#ffffff',
dark: '#ffffff',
contrastText: '#000000',
},
},
})
src/App.js
App.js
import React, { Component } from 'react';
import './App.css';
import Home from './containers/Home';
import Term from './containers/Term';
import Info from './containers/Info';
import { Route, Switch } from 'react-router-dom'
class App extends Component {
render() {
return (
<div className="App">
<BrowserRouter>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/info" component={Info} />
<Route path="/term" component={Term} />
</Switch>
</BrowserRouter>
</div >
);
}
}
export default App;
- BrowserRouterタグとSwitchタグとRouterタグを使ってルーティングを実装。この方の解説めっちゃ分かりやすい。 -> https://qiita.com/kosuke0820/items/77addd20db9e6f7809fe
- Routeタグで、pathごとに、それぞれのコンポーネントに切り替えてくれる。
- exactつけると全体一致、つけないとpathで先頭一致。
src/containers/Home.js
Home.js
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
const styles = theme => ({
home: {
backgroundColor: "red",
width: "50%"
},
});
class Home extends React.Component {
render() {
const { classes } = this.props;
return (
<div className={classes.home}>
<p>未ログイン</p>
<Button variant="contained" color="secondary">
Twitterで登録・ログイン
</Button>
</div>
)
}
}
Home.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles, { withTheme: true })(Home);
- withStyles(styles, { withTheme: true })(Home); で 上部に記載のstylesを適用している。withStylesの書き方は古いみたい。react Hookへの移行を促しているから??? https://qiita.com/gumiTECH/items/9e0f3172b8f85e93cbbe
- stylesのhomeに記載のスタイルが
<div className={classes.home}>
タグに適用されている。 - styleの書き方がcssの書き方と微妙に異なる。ハイフンを使わずに大文字になっていたり。
- Home.propTypes = { classes: PropTypes.object.isRequired, }; でちゃんとpropsの型チェックをしている。propsはコンポネートをカスタマイズできるようにするパラメータ。
src/containers/Info.js
Info.js
import React from 'react';
class Info extends React.Component {
render() {
return (
<h1>Info</h1>
)
}
}
export default Info;
src/containers/Term.js
Term.js
import React from 'react';
class Term extends React.Component {
render() {
return (
<h1>Term</h1>
)
}
}
export default Term;