LoginSignup
6
5

More than 3 years have passed since last update.

ReactへのMaterial-UI、react-routerの導入【初学者のReact✗Railsアプリ開発第3回】

Posted at

やったこと

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の仕組み

超ざっくりな理解としてはこんな感じですかね。
スクリーンショット 2020-01-11 10.18.47.png

  • サイトとしては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に実装できるようにしたパッケージ

今回作るもの

/

スクリーンショット 2020-01-12 6.19.25.png

/term

スクリーンショット 2020-01-12 6.19.15.png

/info

スクリーンショット 2020-01-12 6.19.08.png

  • /,/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;
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5