DEV Community

loading...
Cover image for Rails with React - One Repo - Part 1

Rails with React - One Repo - Part 1

harrymlevine profile image Harry Levine ・4 min read

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, which also includes instructions for Ubuntu and Windows.

Install Ruby 2.5.3

Using 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:

$ 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 by adding the below to the Gemfile:

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

// 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:

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:

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

# app/controllers/pages_controller.rb

class PagesController < ApplicationController
  def index
  end
end

2. Set the root route to this index action

# 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 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:

Discussion

pic
Editor guide
Collapse
montekaka profile image
Josh Chen

Great post! How do we add custom css?
Thanks,
Josh

Collapse
omz profile image
Kurnia Muhamad

Great post Harry! How do you handle authentication?