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
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.
Using rbenv call:
$ rbenv install 2.5.3
$ gem install rails -v 5.2.1
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
- skips adding Test unit
- uses Postgresql for its database
$ rails _5.2.1_ new rails-with-react -T -d postgresql --webpack=react
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
Install the rspec-rails gem by adding the below to the Gemfile:
group :development, :test do
gem 'rspec-rails', '~> 3.8'
endRun the following commands to complete the installation:
$ gem install bundler
$ bundle install
$ rails generate rspec:install
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
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.
First we'll create our base App.js component:
- Underneath the
app/javascript/folder, create acomponentsfolder - Within the
componentsfolder, create the first component calledApp.js - 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 AppNext 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:
- Rename
hello_react.jsxtoindex.js - 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
}- Import and render the new
Appcomponent
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')),
)
})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
- Create an
app/controllers/pages_controller.rbwith an emptyindexaction
# app/controllers/pages_controller.rb
class PagesController < ApplicationController
def index
end
end- Set the
rootroute to thisindexaction
# config/routes.rb
Rails.application.routes.draw do
root 'pages#index'
end- Create an empty
app/views/pages/index.html.erbview file for rendering theindexaction
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.
- Add the
javascript_pack_tagto theapp/views/pages/index.html.erbfile, injectingindex.js
# app/views/pages/index.html.erb
<%= javascript_pack_tag 'index' %>
- Start the rails server
$ rails s
- Visit
http://localhost:3000/
If you see Hello world!, you have successfully set React as a view layer for your Rails app!
There are two more tutorials in this series:
- Part 2 of 3: Integrating React Router
- Part 3 of 3: Handling requests between React and Rails