LoginSignup
10
10

More than 3 years have passed since last update.

Reactを使ったRails環境でのフロント実装 〜Material UIの表示まで〜

Last updated at Posted at 2020-05-08

はじめに

Reactを書いていると、Material UIを使うことも多いかと思います。
それをRails環境でも使用できたらと思い、実際にやってみました。
ReactをRailsで使う方法はいくつかありますが、今回はwebpackerを使用して動かしていきます。
まずwebpackerとは何なのか、全体像を掴んでから始める方がいいと思いますので、以下の記事をざっと読んでからスタートすると後々の理解が深まると思います。
webpack学習の基本のき
もし間違えている箇所があればご指摘をいただければ幸いです。

環境

  • Ruby 2.5.1
  • Rails 6.0.2.2
  • Yarn 1.22.4
  • Node v12.16.1

まずは環境構築(Rails / React / webpacker)

使用するディレクトリを作成し、そのディレクトリに移動します。

$ mkdir myapp
$ cd myapp

Gemfileの作成

$ bundle init
Writing new Gemfile to /myapp/Gemfile

Gemfileの中のrailsのコメントアウトを外します。

Gemfile
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem "rails"

コメントアウトができたら、bundle installでgemをインストールします。

$ bundle install --path vendor/bundle

このようにbundle installだけでなく、--pathとパス指定を加えることで、そのアプリのディレクトリの中だけにインストールされます。
今回だとRailsアプリ(myapp)のルートディレクトリの下のvender/bundleディレクトリにインストールされます。
以下のような記載が出ればインストール完了です。

Bundle complete! 1 Gemfile dependency, 43 gems now installed.
Bundled gems are installed into `./vendor/bundle`

次に、以下のコマンドでwebpackerと同時にReactをインストールします。今回データベースはMySQLを使用したので末尾に--database=mysqlと記載します。

$ bundle exec rails new . --webpack=react --database=mysql

Gemfileを上書きする確認のメッセージが出るので、yを入力してEnterで先に進みます。

       exist  
   identical  README.md
   identical  Rakefile
   identical  .ruby-version
   identical  config.ru
   identical  .gitignore
    conflict  Gemfile
Overwrite /myapp/Gemfile? (enter "h" for help) [Ynaqdhm]

各種インストールが始まります。

Initialized empty Git repository in /Users/katakawaryouhei/Desktop/React/myapp/.git/
      create  package.json
      create  app
      create  app/assets/config/manifest.js

---略---

Bundle complete! 17 Gemfile dependencies, 74 gems now installed.
Bundled gems are installed into `./vendor/bundle`

---略---

✨  Done in 6.89s.
Webpacker successfully installed 🎉 🍰
       rails  webpacker:install:react

---略---

✨  Done in 6.34s.
Webpacker now supports react.js 🎉

Railsで必要なファイル、webpacker、Reactのインストールが完了しました。
Gemfileを確認すると、しっかりwebpackerもインストールできていることがわかります。

Gemfile
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'

またこの時点でjsxファイルが生成されています。

app/javascript/packs/hello_react.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

------

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Hello name="React" />,
    document.body.appendChild(document.createElement('div')),
  )
})

Railsの動作確認

次にパスワードを打ち込み、MySQLを立ち上げます。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['RAILS_DATABASE_USER'] %>
  password: <%= ENV['RAILS_DATABASE_PASSWORD'] %>
  host: localhost

今回パスワード等の機密情報の管理は、Dotenv-railsというgemを使用して環境変数にしています。詳しくは以下の記事が参考になると思います。
[Ruby on Rails]環境変数の設定方法(.bash_profile、Dotenv-rails)

$ rails db:create

これでデータベースが立ち上がったので、Railsが動くか確認してみます。

$ bundle exec rails s

上記コマンド入力後、ブラウザのアドレス欄に localhost:3000 を入力します。
以下の画面が表示されればRailsが動作できています!
スクリーンショット 2020-05-07 18.15.22.png

動作確認ができたのでRailsサーバーは、Ctrl + C で一旦停止します。

React動作確認

まずはReactを表示するための画面を作りたいので、コントローラーとビューを作成します。

$ bundle exec rails g controller home index

      create  app/controllers/home_controller.rb
       route  get 'home/index'
      invoke  erb
      create    app/views/home
      create    app/views/home/index.html.erb
      invoke  test_unit
      create    test/controllers/home_controller_test.rb
      invoke  helper
      create    app/helpers/home_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/home.scss

ルーティングは以下のように変更します。

config/routes.rb
Rails.application.routes.draw do
  root to 'home#index'
end

続いて、Reactを表示させる為に、以下のように記載しERBファイルでJSファイルを読み込みます。

app/views/home/index.html.erb
<%= javascript_pack_tag 'application' %>

javascript_pack_tagは、JavaScriptをapp/javascript/packs配下から読み込むwebpacker用のヘルパーメソッドです。
'application'はapp/javascript/packs/application.jsを示します。
他のファイルを指定したい場合は、javascript_pack_tag '他のファイル名'と変更すれば、app/javascript/packs配下の別のファイルを読み込めます。
今回は'application'としました。application.jsを以下の1行を追加します。

app/javascript/packs/appication.js
require('./hello_react.jsx')

それでは準備ができたのでサーバーを起動していきます。
開発環境では、Rails用のサーバーとwebpack用のサーバーの両方の起動が必要になるので、コマンドも別のターミナルでそれぞれ打ち込む必要があります。

$ bundle exec rails s
$ bin/webpack-dev-server

これでも『Hello React!』の画面が立ち上がるかと思いますが、package.jsonを以下の様に書き加えると、

package.json
+ "scripts": {
    "start": "bundle exec rails s & bin/webpack-dev-server"
  },

以下のコマンド1回で済みます。

$ yarn start

上記コマンド入力後、ブラウザのアドレス欄に 再度localhost:3000 を入力します。
以下の画面が表示されればReactが動作できています!

スクリーンショット 2020-05-07 22.39.43.png

動作確認後のスタイル変更(Material UIの導入)

Reactの動作が確認できたので、
- CSSの反映
- Reactコンポーネント分割
- Rails上でMaterial UIの導入
までやっていきたいと思います。

まずはCSSを反映させたいので、以下のように変更を加えます。

app/views/home/index.html.erb
<%= stylesheet_pack_tag 'application' %>
<%= javascript_pack_tag 'application' %>

先程のjavascript_pack_tagに加えて、stylesheet_pack_tag 'application'を記載しました。
同じ要領で、application.jsに以下の1行を追加します。

app/javascript/packs/appication.js
require('./stylesheets/hello_react.css')

まだファイルを作っていないので、新しくフォルダとファイルを作成します。
後々使うファイルも全て作成してしまいます。

app/
  └ javascript/
       └ packs/
           ├ stylesheets/
           │     └ hello_react.css
           ├ App.jsx
           ├ application.js
           └ hello_react.jsx

具体的には、以下を新規で作成しました。
- stylesheets/
- stylesheets/hello_react.css
- App.jsx

準備ができましたので、CSSファイルに記載を加えます。

app/javascript/packs/stylesheets/hello_react.css
body {
  background-color: aqua;
}

わかりやすいように背景色を青色にしました。
これでリロードすると、CSSが反映されていることがわかります。
スクリーンショット 2020-05-08 02.52.20.png

それでは、React側でコンポーネントを切り分けていきます。
下記コードのように各ファイルの記載を変更します。

app/javascript/packs/hello_react.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import App from './App'

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <App />,
    document.body.appendChild(document.createElement('div')),
  )
})
app/javascript/packs/App.jsx
import React from 'react'

function App() {
  return (
    <div>
      <h2>これはReactです。</h2>
    </div>
  )
}

export default App

わかりやすいように、Ruby側のファイルもERB記法で下記のように追記します。

app/views/home/index.html.erb
<h2>これはRubyです。</h2>
<hr color="green">

<%= stylesheet_pack_tag 'application' %>
<%= javascript_pack_tag 'application' %>

これでリロードすると、ReactとRubyの両方で記載が完了していることがわかります。
スクリーンショット 2020-05-08 03.05.33.png
最後に、Material UIを表示させていきます。

$ yarn add @material-ui/core

warning @material-ui/core > popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...

---略---

├─ jss-plugin-nested@10.1.1
├─ jss-plugin-props-sort@10.1.1
├─ jss-plugin-rule-value-function@10.1.1
├─ jss-plugin-vendor-prefixer@10.1.1
├─ popper.js@1.16.1
└─ react-transition-group@4.4.1
✨  Done in 16.10s.

今回はCircle Progressを表示させてみるので、App.jsxを再度以下のように編集します。

app/javascript/packs/App.jsx
import React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress';

function App() {
  return (
    <div>
      <h2>これはReactです。</h2>
      <CircularProgress />
    </div>
  )
}

export default App

これでリロードすると、無事Material UIも表示できたかと思います!
sampleapp.gif

参考

https://github.com/rails/webpacker
https://www.playfulit.net/articles/2019/01/27/webpacker-react-frontend-on-ruby-on-rails/
https://free-engineer.hatenablog.com/entry/2018/04/26/165941

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