Rails with React - One Repo - Part 1
Tags: rails, react
Published: 2018-11-14 22:24:22

---
title: Rails with React - One Repo - Part 1
published: true
description: Tutorial series that walks you through creating a Ruby on Rails web application that uses React as its view layer, all in one repository.
tags: rails, react
cover_image: https://thepracticaldev.s3.amazonaws.com/i/j0xrwz8vsxkvc5b4nndy.png
---

## Part 1 of 3: Setting React as the view layer

This tutorial series will walk you through creating a Ruby on Rails web application that uses React as its view layer, all in one repository.

The primary technologies that will be included are:

- Rails 5.2.1
  - Ruby 2.5.3
  - Postgresql
  - Webpacker
  - RSpec
- React 16
  - React router
  - Axios

All of the code for this series resides at: https://github.com/oddballio/rails-with-react

## Setup

You'll first need to install the current versions of Ruby and Rails.  These instructions assume a MacOS with rbenv.  They follow this fantastic, well maintained [resource for Ruby and Rails environment setup](https://gorails.com/setup/osx/10.14-mojave), which also includes instructions for Ubuntu and Windows.

### Install Ruby 2.5.3

Using [rbenv](https://github.com/rbenv/rbenv) call:

```
$ rbenv install 2.5.3
```

### Install Rails 5.2.1

```
$ gem install rails -v 5.2.1
```

### Create new Rails/React web app

Our web app will be called `rails-with-react`.  Here is the command you'll run in order to create a Rails app that:

- uses Rails version 5.2.1
- [integrates Webpacker with React](https://github.com/rails/webpacker#react)
- skips adding Test unit
- uses Postgresql for its database

```
$ rails _5.2.1_ new rails-with-react -T -d postgresql --webpack=react
```

### Set the Ruby version

The Ruby version will need to be updated in your application.  `cd` into the new directory, and change the ruby version to `2.5.3` in both of these files:

- `Gemfile`
- `.ruby-version`

### Add RSpec for spec support

Install the [rspec-rails gem](https://github.com/rspec/rspec-rails) by adding the below to the `Gemfile`:

```ruby
group :development, :test do
  gem 'rspec-rails', '~> 3.8'
end
```

Run the following commands to complete the installation:

```
$ gem install bundler
$ bundle install
$ rails generate rspec:install
```

### Complete the setup

Lastly you'll run the `bin/setup` script to complete the installations:

```
$ bin/setup
```

Should you receive this error:

```
== Command ["bin/rails db:setup"] failed ==
```

Try:

```
$ rails db:migrate
$ bin/setup
```

## Set React as the view layer

From the `--webpack=react` flag in the setup, you'll note the presence of a new `app/javascript/` directory.  This is where all of our React related code will live.

By default, Rails has included the following boilerplate files and structure:

```
app/
|
|-- javascript/
|   |-- packs/
        |-- application.js
        |-- hello_react.jsx
```

We are going to make a few changes, to set the React app to follow a more traditional, scalable component based structure.

### Components

First we'll create our base `App.js` component:

**1.** Underneath the `app/javascript/` folder, create a `components` folder
**2.** Within the `components` folder, create the first component called `App.js`
**3.** Begin with a basic "Hello world" class component structure

```jsx
// app/javascript/components/App.js

import React from 'react'

class App extends React.Component {
  render() {
    return (
      <div>
        Hello world!
      </div>
    )
  }
}

export default App
```

### Index.js

Next we'll create an `index.js` file that will be injected into a Rails view file, containing our React app.  To accomplish this, we will:

**1.** Rename `hello_react.jsx` to `index.js`
**2.** **Remove** this boiler plate code:

```jsx
import PropTypes from 'prop-types'

const Hello = props => (
  <div>Hello {props.name}!</div>
)

Hello.defaultProps = {
  name: 'David'
}

Hello.propTypes = {
  name: PropTypes.string
}
```

**3.** Import and render the new `App` component

The `index.js` file should look like this:

```jsx
// app/javascript/packs/index.js

// Run this example by adding <%= javascript_pack_tag 'hello_react' %> to the head of your layout file,
// like app/views/layouts/application.html.erb. All it does is render <div>Hello React</div> at the bottom
// of the page.

import React from 'react'
import ReactDOM from 'react-dom'
import App from '../components/App'

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <App />,
    document.body.appendChild(document.createElement('div')),
  )
})
```

### Root Rails view for the React app

We will now create the single Rails view where the entire React app will be injected into.  Following conventional Rails patterns, this will involve a:

- controller action
- root route
- view

**1.** Create an `app/controllers/pages_controller.rb` with an empty `index` action

```ruby
# app/controllers/pages_controller.rb

class PagesController < ApplicationController
  def index
  end
end
```

**2.** Set the `root` route to this `index` action

```ruby
# config/routes.rb

Rails.application.routes.draw do
  root 'pages#index'
end
```

**3.** Create an empty `app/views/pages/index.html.erb` view file for rendering the `index` action

### Inject React into Rails

To bridge the two worlds, React and Rails, you will use the Rails [`javascript_pack_tag`](https://github.com/rails/webpacker#usage) to inject the entire React application into the Rails view.

**1.** Add the `javascript_pack_tag` to the `app/views/pages/index.html.erb` file, injecting `index.js`

```
# app/views/pages/index.html.erb

<%= javascript_pack_tag 'index' %>
```

**2.** Start the rails server

```
$ rails s
```

**3.** Visit `http://localhost:3000/`

If you see **Hello world!**, you have successfully set React as a view layer for your Rails app!

### Next Steps

There are two more tutorials in this series:

- [Part 2 of 3: Integrating React Router](https://dev.to/harrymlevine/rails-with-react---one-repo---part-2-4a6o)
- [Part 3 of 3: Handling Requests Between React and Rails](https://dev.to/harrymlevine/rails-with-react---one-repo---part-3-nk)