if it does't challenge you, it can't change you

RubyのWebエンジニアやってます。主にRuby on Railsのことで勉強になったこと書いていきます。

Rails5.1にReactを導入

react-railsとwebpackerの場合

インストール

Gemfileに以下を追加して、bundle install

gem 'react-rails' 
gem 'webpacker'

installコマンド実行

rails webpacker:install  
rails webpacker:install:react   

これでReactに必要なフォルダやファイルが生成されてReactが入る。 webpackerによりapp/javascript/packsにhello_react.jsxが生成されているのがわかる。
これはReactを使って、「Hello React」を表示させる簡単なものである。 そして、webpackerにより使えるようになったを追加していく。

Reactを使って「Hello React」を表示

コントローラー、ビュー、ルーティングを生成
rails g controller sample index

app/views/layouts/application.html.erbに以下のようにjavascript_pack_tagを追加

<!DOCTYPE html>
<html>
<head>
  <title>CalculatorReact2</title>
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag 'application', media: 'all' %>
  <%= javascript_include_tag 'application' %>
  <%= javascript_pack_tag 'hello_react' %>
</head>
<body>
  <%= yield %>
</body>
</html>

この状態でrailsサーバーを起動すると、「Hello React」が表示される。

react-railsのReactコンポーネントの作成

react-railsではReactコンポーネントは以下のコマンドで作成できる。

rails g react:component コンポーネント名

そうするとapp/javascript/component/ の配下にコンポーネント名.jsが生成される。

例えば、rails g react:component calculator だと

app/javascript/component/calculator.jsが生成される。

あとは好きなviewのそのコンポーネントを使いたいところで
<% react_component 'calculator' %>というようなview helperを記載しておくと、app/javascript/component/calculator.jsを読み込んでくれる。

app/views/layouts/application.html.erbには<%= javascript_pack_tag 'application' %>を記載しておけば読み込んでくれる。

react-rails のapplication.js

webpackerと比べて以下が追加されている。

var componentRequireContext = require.context("components", true)
var ReactRailsUJS = require("react_ujs")
ReactRailsUJS.useContext(componentRequireContext)

rails g react:componet で作成したコンポーネントファイルに以下を書かなくてもいい。

import ReactDOM from 'react-dom';
ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

 

webpackerのみ場合

react-railsがないとrailsサーバーを起動しても、Reactは動いてくれない。

railsサーバー起動後、別ターミナルで以下を叩きコンパイルする

./bin/webpack-dev-server

このままではreactを変更するたびにコンパイルしなければいけないので、

package.jsonに以下を追加し、

"scripts": {
"start": "rails s & bin/webpack-dev-server"
},

yarn startで同時に行ってくれる。

webpackerで読み込むコンポーネント

コンポーネントを入れるフォルダを作成

webpackerのみの場合、app/javascript/配下にはpacksフォルダしか生成されないので、ここで任意のフォルダを作成する。

app/javascript/calculator/

コンポーネントファイルを作成

app/javascript/calculator/calculator.js

import React, { Component } from 'react';

class Calculator extends Component {
 render() {
  return (
   <div>
    <h1>Calculator is working!!</h1>
   </div>
  )
 }
}
export default Calculator;

app/javascript/calculator/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import Calculator from './calculator';

document.addEventListener('DOMContentLoaded', ()=> {
  const container = document.body.appendChild(document.createElement('div'));
  ReactDOM.render(<Calculator/>, container)
})

Viewで読み込む

app/javascript/packs/calculator.jsを作成し、その中に読み込むフォルダを記載

import 'calculator'

そうするとapp/javascript/calculator/ 配下のコンポーネントをimportする。

あとはapp/views/layouts/application.html.erbのHEADタグ内にreact-railsの時と同じようにjavascript_pack_tagを追加し、app/javascript/packs/calculator.jsを指定してあげるとviewで読み込んでくれる。

<!DOCTYPE html>
<html>
<head>
  <title>CalculatorReact2</title>
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag 'application', media: 'all' %>
  <%= javascript_include_tag 'application' %>
  <%= javascript_pack_tag 'calculator' %>
</head>
<body>
  <%= yield %>
</body>
</html>