Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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ビギナーズガイドに沿って進めていきたい...。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away