LoginSignup
26
26

ReactではBootstrapの代わりにMaterial-UIを使ってみる

Last updated at Posted at 2017-04-09

superAgentでRailsとReactをAPI連携しつつ、簡易的な表テーブルを作成するの続き。

前回はRailsとReactをAPI連携させて、表テーブルを作成するというところまでやりました。
前回の完成物がこちら。

image

今回は「Reactビギナーズガイド」に沿って表テーブルの編集機能を作っていく予定でしたが、ダサすぎてモチベーションが上がらないので、先にデザイン部分をいい感じにしていきたいと思います。

Bootstrap的なやつが使いたい

僕は普段Railsで「何か作ってみるか」みたいなときは大抵Bootstrapを突っ込んでいるのですが、Reactではどうすべきなのかなと思い調べてみたところ、参考になる記事がありました。

この記事によると、

  • React を前提とした React コンポーネントセット
  • 既存の CSS を移植した React コンポーネントセット

という2パターンがあるらしいということが分かります。
さらに読み進めていくと前者の方が都合が良さそうなので、今回はMaterial-UIというコンポーネントライブラリを使っていきたいと思います。

image

Material-UIについてざっと概要を知りたいという方は、以下の記事がGIFや画像付きで分かりやすいかと思います。

Material-UIのインストール

$ npm install --save material-ui

コンポーネントにテーマをインポートする

公式サイトのUsageを読むと、Material-UIのコンポーネントを使用するためには、テーマをインポートする必要があることが分かります。

公式サイトに倣ってコードを追記していきます。

books.js
import React from 'react'
import ReactDOM from 'react-dom'
import request from 'superagent'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider' // 追記

class Books extends React.Component {
  constructor() {
    super()
    this.state = {
      books: [],
    }
  }

  componentWillMount() {
    this.getState()
  }

  getState() {
    request
      .get('/api/books/index')
      .end((error, res) => {
      if (!error && res.status === 200) {
        const json = JSON.parse(res.text)
        this.setState({
          books: json.books,
        })
      } else {
        console.log(error)
      }
    })
  }

  render() {
    const {books} = this.state
    const headers = books[0] != null ? Object.keys(books[0]) : []
    return (
      <MuiThemeProvider> // 追記
        <div>
          <h1>BookApp</h1>
          <table>
            <thead>
              <tr>
                {headers.map((header, index) => {
                  return (
                    <th key={index}>{header}</th>
                  )
                })}
              </tr>
            </thead>
            <tbody>
            {books.map((book, index) => {
              return (
                <tr key={index}>
                  {Object.values(book).map((row, index) => {
                    return (
                      <td key={index}>{row}</td>
                    )
                  })}
                </tr>
              )
            })}
          </tbody>
          </table>
        </div>
      </MuiThemeProvider> // 追記
    )
  }
}

ReactDOM.render(
  <Books />,
  document.getElementById("books")
)

MuiThemeProviderは単一の要素をPropsとして渡す必要があるようです。
Usageのようにコンポーネントを渡すか、今回のように<div>...</div>などでラップされた単一の要素を渡せば問題なさそうです。

表テーブルをMaterial-UIを使って書き換える

Material-UIを使用する準備が整ったので、実際に表テーブルのコードを書き換えていきます。

books.js
import React from 'react'
import ReactDOM from 'react-dom'
import request from 'superagent'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
// 以下追記
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn} from 'material-ui/Table'

class Books extends React.Component {
  constructor() {
    super()
    this.state = {
      books: [],
    }
  }

  componentWillMount() {
    this.getState()
  }

  getState() {
    request
      .get('/api/books/index')
      .end((error, res) => {
      if (!error && res.status === 200) {
        const json = JSON.parse(res.text)
        this.setState({
          books: json.books,
        })
      } else {
        console.log(error)
      }
    })
  }

  render() {
    const {books} = this.state
    const headers = books[0] != null ? Object.keys(books[0]) : []
    return (
      <MuiThemeProvider>
        <div>
          <h1>BookApp</h1>
          // <table>, <thead>, <tbody>, <tr>, <th>, <td>を変更
          // 詳しくは (http://www.material-ui.com/#/components/table) を参照
          <Table>
            <TableHeader>
              <TableRow>
                {headers.map((header, index) => {
                  return (
                    <TableHeaderColumn key={index}>{header}</TableHeaderColumn>
                  )
                })}
              </TableRow>
            </TableHeader>
            <TableBody>
              {books.map((book, index) => {
                return (
                  <TableRow key={index}>
                    {Object.values(book).map((row, index) => {
                      return (
                        <TableRowColumn key={index}>{row}</TableRowColumn>
                      )
                    })}
                  </TableRow>
                )
              })}
            </TableBody>
          </Table>
          // ここまで変更
        </div>
      </MuiThemeProvider>
    )
  }
}

ReactDOM.render(
  <Books />,
  document.getElementById("books")
)

ここまでで以下のようなUIになりました。

image

もう少し良い感じにしていきたいので、Material-UIの<Card>というコンポーネントを使ってみたいと思います。

books.js
import React from 'react'
import ReactDOM from 'react-dom'
import request from 'superagent'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn} from 'material-ui/Table'
import {Card, CardHeader} from 'material-ui/Card' // 追記

class Books extends React.Component {
  constructor() {
    super()
    this.state = {
      books: [],
    }
  }

  componentWillMount() {
    this.getState()
  }

  getState() {
    request
      .get('/api/books/index')
      .end((error, res) => {
      if (!error && res.status === 200) {
        const json = JSON.parse(res.text)
        this.setState({
          books: json.books,
        })
      } else {
        console.log(error)
      }
    })
  }

  render() {
    const {books} = this.state
    const headers = books[0] != null ? Object.keys(books[0]) : []
    return (
      <MuiThemeProvider>
        <Card> // 変更
          <CardHeader title="BookApp" /> // 変更
          <Table>
            <TableHeader>
              <TableRow>
                {headers.map((header, index) => {
                  return (
                    <TableHeaderColumn key={index}>{header}</TableHeaderColumn>
                  )
                })}
              </TableRow>
            </TableHeader>
            <TableBody>
              {books.map((book, index) => {
                return (
                  <TableRow key={index}>
                    {Object.values(book).map((row, index) => {
                      return (
                        <TableRowColumn key={index}>{row}</TableRowColumn>
                      )
                    })}
                  </TableRow>
                )
              })}
            </TableBody>
          </Table>
        </Card> // 変更
      </MuiThemeProvider>
    )
  }
}

ReactDOM.render(
  <Books />,
  document.getElementById("books")
)

のっぺりしていた表テーブルがカードにすることで立体感がでました!

image

まとめ

Material-UIはQiitaでもいくつか記事があるし、ドキュメントもしっかりしているのでかなり使いやすいと思います!
そろそろReactビギナーズガイドに沿って進めていきたい...。

26
26
1

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
26
26