How to use React with Ruby on Rails 6

hrishio

Hrishi Mittal

Posted on December 8, 2019

How to use React with Ruby on Rails 6

Note: This tutorial is based on the latest versions of Rails (6.0.1) and React (16.12).

There are a few different ways to use React inside Ruby on Rails apps. With the recent improvements in native support in Rails for JavaScript tooling, it's now easier than ever to start using JavaScript libraries, including React, with Rails.

  1. webpacker

  2. react-rails

  3. react_on_rails

You can also use React in a separate frontend app with a Rails API. A new tutorial on that is coming shortly. Sign up to the Learnetto newsletter to get it first.

1. webpacker

This tutorial is based on Ruby 2.6.5 and the latest Rails gem (6.0.1 at the time of writing this tutorial).

Create a new Rails app:

rails new eventlite --webpack=react
Enter fullscreen mode Exit fullscreen mode

This creates a Rails app with Webpack configured and a new directory for storing JavaScript code and a couple of new files:

app/javascript:
  └── packs:
      └── application.js
      └── hello_react.jsx
Enter fullscreen mode Exit fullscreen mode

All files in the new app/javascript/packs directory are compiled by Webpack.

There's one example React file hello_react.jsx, which defines a simple functional React component called Hello that can display the words "Hello React!" on a page. It can also take a prop called name to display it instead of the word "React".


import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

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

Hello.defaultProps = {
  name: 'David'
}

Hello.propTypes = {
  name: PropTypes.string
}

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

We can use this component on any page by linking it with the javascript_pack_tag helper method.

We're going to build a simple one-page application for creating and listing events.

So let's start by creating a new events view file app/views/events/index.html.erb and use the javascript_pack_tag method inside it to display the default example Hello component:

<%= javascript_pack_tag 'hello_react' %>
Enter fullscreen mode Exit fullscreen mode

Let's create the associated controller and index action for events:

class EventsController < ApplicationController
  def index
  end
end
Enter fullscreen mode Exit fullscreen mode

And make that our root path in config/routes.rb:

root 'events#index'
Enter fullscreen mode Exit fullscreen mode

Then we can start the Rails server:

rails start
Enter fullscreen mode Exit fullscreen mode

Go to http://localhost:3000 to see the result:

I focus on using React with webpacker in the new version of my Complete React on Rails Course.

2. react-rails

react-rails is the official React community gem for integrating React with Rails. The main benefit of using this gem is the react_component helper method which makes it easy to pass Rails data to components.

You can use react-rails with webpacker or with Sprockets (to bundle the JSX into the asset pipeline).

a. Using react-rails with webpacker

Add the react-rails gem to the Gemfile of the app we created above and install it:

gem 'react-rails'
Enter fullscreen mode Exit fullscreen mode
$ bundle install
Enter fullscreen mode Exit fullscreen mode

Then run the react-rails generator:

rails generate react:install
Enter fullscreen mode Exit fullscreen mode

This creates the app/javascript/components/ directory for storing your React components. It also sets up configuration for mounting components and server-side rendering.

The gem adds the following lines in application.js to load the gem's JavaScript code (react_ujs) and all code inside the components directory:

var componentRequireContext = require.context("components", true);
var ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);
Enter fullscreen mode Exit fullscreen mode

We can use the same Hello component we created earlier with webpacker by moving it to the new components directory. We also need to rename the file to 'Hello.jsx' (case sensitive).

react-rails provides a convenient helper method called react_component to render React components inside views.

First let's export the component and remove the call to ReactDOM.render on document load. The component code will now look like this:

import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'

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

Hello.defaultProps = {
  name: 'David'
}

Hello.propTypes = {
  name: PropTypes.string
}

export default Hello
Enter fullscreen mode Exit fullscreen mode

And now inside our view file events/index.html.erb, we can replace the javascript_pack_tag with a call to react_component:

<%= react_component("Hello") %>

We can also pass another value for the name prop easily:

<%= react_component("Hello", { name: "react-rails" }) %>

The react-rails gem also provides a component generator to automatically create a basic component by passing it a component name and props (with their proptypes). It's similar to Rails generators for creating models and scaffolds:

$ rails generate react:component HelloWorld greeting:string
Enter fullscreen mode Exit fullscreen mode

b. Using react-rails with sprockets

react-rails also gives you the option to continue using the default Rails asset pipeline to serve your React code, instead of using webpacker.

You can use this option by installing just the react-rails gem without the webpacker gem, and following the same steps as above.

Note that the webpacker gem is included in Rails by default since version 6. So, for an existing Rails 6 app, you'll need to uninstall it and move all your JavaScript code to the classic app/assets/javascripts directory. Or you can generate a new Rails app without webpacker by using the --skip-javascript flag:

rails new eventlite --skip-javascript
Enter fullscreen mode Exit fullscreen mode

I strongly recommend you avoid this route. It's best to use the new Rails standard webpacker so that you can get all the benefits of the latest JavaScript tooling and you don't create legacy code that will get out of date very quickly.

3. react_on_rails

The other most popular third-party gem for integrating React into Rails is the react_on_rails gem created by ShakaCode.

Similar to the react-rails gem, now that Rails already provides an easy way to use React via webpacker, you have to see if the stated benefits of the react_on_rails gem apply to your situation.

The main benefits include better support for server side rendering, easy passing of props to React components (with the react_component method just like react-rails), and Redux and React Router integration.

This gem requires webpacker. To use it in a new Rails app with webpacker, let's install the gem first.

Add it to to the Gemfile:

gem 'react_on_rails', '11.1.4' # Use the exact gem version to match npm version
Enter fullscreen mode Exit fullscreen mode

The run:

$ bundle install
Enter fullscreen mode Exit fullscreen mode

After installing the gem, we must first commit the code to git or the gem's install generator won't run. This is an easy step to miss, so make sure you do it before you proceed.

Once you've committed the code to git, run the install generator and start the Rails server:

$ rails generate react_on_rails:install
Enter fullscreen mode Exit fullscreen mode

This generates some example code and configuration and installs some dependencies.

This gem places all React code under a new app/javascript/bundles directory. This is just a convention, you can use other directories if you like.

The gem install generated automatically generates an example component HelloWorld stored in app/javascript/bundles/HelloWorld/components/HelloWorld.jsx.

It also generates a file called hello-world-bundle.js inside the app/javascript/packs directory. This is where the HelloWorld component code is imported and registered with react_on_rails so that it can be used in views.

import ReactOnRails from 'react-on-rails';

import HelloWorld from '../bundles/HelloWorld/components/HelloWorld';

// This is how react_on_rails can see the HelloWorld in the browser.
ReactOnRails.register({
  HelloWorld,
});
Enter fullscreen mode Exit fullscreen mode

react_on_rails also provides a react_component helper method for rendering components inside views and pass props to them. You can see an example in the automatically generated view app/views/hello_world/index.html.erb:

<h1>Hello World</h1>
<%= react_component("HelloWorld", props: @hello_world_props, prerender: false) %>
Enter fullscreen mode Exit fullscreen mode

Start the Rails server and visit http://localhost:3000/hello_world to see the component in action:

That’s a quick overview of 3 ways to get started with using React inside your Rails app.

I recommend starting with webpacker and using other gems only if you need their specific benefits.

Once an app is big and complex enough, a lot of developer teams choose to move their React code into a separate frontend app and use the Rails app as a backend API.

I’ll shortly publish another tutorial teaching the basics of that. Sign up to the Learnetto newsletter to get it first.

And if you want to learn it all in depth to use React professionally with Rails, check out the new version of my Complete React on Rails Course.

💖 💪 🙅 🚩
hrishio
Hrishi Mittal

Posted on December 8, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related