Railsにこれから初めて触れる方を対象にしたチュートリアルです
RailsとReact.jsを使ってサンプルアプリを作成します
まず、rails newを実行し、Railsアプリのひな型を作成します。
rails new reactjs --webpack=react
--webpackはRailsでWeboackを使いやすくしたWebpackerというものを使用するというオプションです
Vue、React、Angular、Elm、Stimulusを使用することができます
今回はReact.jsを使用するので--webpack=reactとしています
次に、作成したRailsアプリのディレクトリへと移動します。
cd reactjs
Webpackerを使う場合、ruby ./bin/webpack-dev-serverというコマンドを実行しつつ、rails sでローカルサーバーを起動する必要があります
その為、現状のままではターミナルを複数開いておく必要があり、少々面倒です
そこで、複数のコマンドを並列して実行できるforemanを使用します
まず、Gemfileにgem 'foreman'を追記します
gem 'foreman'
その後、bundle install
bundle install
この時、sqlite3がインストールできないエラーが発生するかもしれません その場合は以下のようにsqlite3のバージョンを修正してbundle installを実行してください
gem 'sqlite3', '1.3.13'
bundle install
次に、foremanで使用するProcfile.devを作成します
web: bundle exec rails s
webpacker: ruby ./bin/webpack-dev-server
あとは、foreman start -f Procfile.devをターミナルで実行するだけです
foreman start -f Procfile.dev
localhost:5000にアクセスできればOkです(foremanを使用する場合、使用するポートが5000へと変更されています)
rails g controller コマンドを使い、コントローラーを作成します
rails g controller web index
その後、config/routes.rbを以下のように編集します
Rails.application.routes.draw do
  root 'web#index'
end
foreman start -f Procfile.devを実行して、localhost:5000でページが表示されていればOKです
まず、app/views/web/index.html.erbを以下のように変更します
<%= javascript_pack_tag 'hello_react' %>
最初に実行したrails newの段階でapp/javascript/packs/hello_react.jsが作成されています
それを<%= javascript_pack_tag 'hello_react' %>を使い、読み込んでいます
app/views/web/index.html.erbを編集後、foreman start -f Procfile.devを実行して、Hello Reactと表示されていればOKです!
次に、React.js経由でBootstrapを使用してみたいと思います
まずはyarn add react-bootstrap bootstrapを実行し、React.js用のBootstrapを導入します
yarn add react-bootstrap bootstrap
次に、各コンポーネントを作成していきます
Headerコンポーネントとして利用するapp/javascript/packs/components/layouts/Header.jsxを作成します
import React from 'react'
import { Navbar, Nav, NavDropdown, Form, FormControl, Button,  } from 'react-bootstrap'
const Header = () => (
    <Navbar bg="light" expand="lg">
        <Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="mr-auto">
                <Nav.Link href="#home">Home</Nav.Link>
                <Nav.Link href="#link">Link</Nav.Link>
                <NavDropdown title="Dropdown" id="basic-nav-dropdown">
                    <NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
                    <NavDropdown.Item href="#action/3.2">Another action</NavDropdown.Item>
                    <NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
                    <NavDropdown.Divider />
                    <NavDropdown.Item href="#action/3.4">Separated link</NavDropdown.Item>
                </NavDropdown>
            </Nav>
            <Form inline>
                <FormControl type="text" placeholder="Search" className="mr-sm-2" />
                <Button variant="outline-success">Search</Button>
            </Form>
        </Navbar.Collapse>
    </Navbar>
)
export default Header;
react-bootstrapは以下のように各コンポーネントを呼び出して使います
import { Navbar, Nav, NavDropdown, Form, FormControl, Button,  } from 'react-bootstrap'
次に、Mainコンポーネントとして利用するapp/javascript/packs/components/layouts/Header.jsxを作成します
import React from 'react'
const Main = () => (
    <div className="container">
        <h1>Hello World! with React.js & Rails!</h1>
    </div>
)
export default Main;
Footerコンポーネントとして利用するapp/javascript/packs/components/layouts/Footer.jsx作成します
import React from 'react'
const Footer = (props) => {
    const {year} = props
    return (
        <div>
            Created Time {year}
        </div>
    )
}
export default Footer;
あとは、app/javascript/packs/index.jsを以下のように作成します
import React from 'react';
import ReactDOM from 'react-dom';
import Header from './components/layouts/Header'
import Main from './components/web/Main'
import Footer from './components/layouts/Footer'
class App extends React.Component {
    state = {
        year: 2019
    }
    render() {
        return (
            <div>
                <Header />
                <Main />
                <Footer year={this.state.year} />
            </div>
        );
    }
}
document.addEventListener("DOMContentLoaded", e => {
    ReactDOM.render(<App />, document.body.appendChild(document.createElement('div')))
})
最後に、app/views/web/index.html.erbを以下のように編集します
<link
  rel="stylesheet"
  href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
  integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
  crossorigin="anonymous"
></link>
<%= javascript_pack_tag 'index' %>
react-bootstrapではCSSが含まれていません
そのため、以下のようにCDN経由でCSSを導入する必要があります
<link
  rel="stylesheet"
  href="https://maxcdn.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
  integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
  crossorigin="anonymous"
></link>
あとは、foreman start -f Procfile.devをターミナルで実行します
localhost:3000にアクセスしてBootstrapが適用されていればOKです!