In my time at Flatiron School we learned a lot about Ruby on Rails and React, building complete projects with both. Thus far I had only handled using these two technologies together in one way: create a React front-end that is fed data from a Rails API. This is certainly a great way to handle things, but as I started building my own projects I found myself wanting for a more elegant solution than splitting things up into two separate projects that were just able to talk to each other. I found myself thinking why isn't there a way to take advantage of Rails' MVC pipeline and use React directly within the Rails views. After some searching and googling I found a solution that seems to do exactly that: the react-rails
gem.
I'd like to use this post as an opportunity to walk anyone who may have been in a similar boat as myself through the process of setting everything up in a single project. If you are someone who likes to go straight to documentation and play around with things yourself, I encourage you to check those out here. The setup instructions that come with them are fantastic, and for the most part I will be walking through those instructions getting my own project set up. For reference, my project will be using Webpacker with Rails 6x.
Getting Started
Getting started with react-rails
is fairly simple and straightforward. If you have ever used Rails' built in generator tools a lot of what we will be doing will look very familiar. There are just a few configurations we will have to set up to get React hooked into our Rails project correctly.
The first thing we will want to do is create a new Rails project. This can be done most easily using the new
Rails command in the terminal which will also allow you to set up some additional configuration if you'd like.
rails new my-app -T
I like to use the -T
flag when building personal projects as it tells Rails not to initialize the project with auto generated test files. I find they're generally unnecessary for personal projects, and it also leaves you with the option to use testing tools that aren't Rails default later on if you choose.
You can also use the -d
flag to set your project up with a different database tool, as well as any other configuration flags you might want.
Configuring Gems
At this point there are two gems that we want to set up in our project: webpacker
and react-rails
. Go ahead and add those two to your Gemfile to include them as dependencies within your project. webpacker
may already be included from using the project generator (it was in my case), so just make sure that both gems are there and you're good to go.
Installation and Setup
Next we're going to make sure that any gems that we added to the Gemfile in the above step get installed properly. Go ahead and run bundle install
in the terminal to do so.
After we make sure everything is good with bundler and our gems, we're going to run a series of Rails commands to get everything hooked up properly. A command or two may already be configured from the initial project generation, but it doesn't hurt to run all of them just to make sure we have everything set up properly.
rails webpacker:install
rails webpacker:install:react
rails generate react:install
Running the above three commands might take a little bit of time to get everything configured, but after the have successfully run Rails should now be ready to start accepting our React components through it's pipeline.
We should now have:
- an
app/javascript/components/
directory - ReactRailsUJS setup in
app/javascript/packs/application.js
- an
app/javascript/packs/server_rendering.js
The components
directory is where all of our React components will live. ReactRailsUJS makes our Javascript available to the window and allows us access to event handling, lifecycle methods, control over mounting and unmounting, and much more. Finally, the server_rendering.js
file is for server side rendering.
The last thing we will need to do is link the JavaScript pack. If you are using Rails 6, this will have been added by default so you can skip this step. For Rails versions below 6, you will simply place the helper below in the head tag of your application.html.erb
file below turbolinks:
<%= javascript_pack_tag 'application' %>
Component Time
Now that we have all of the setup and configuration set up, we can move on to finally making and rendering some components! react-rails
provides us with an easy to use generator similar to what you might be used to while creating Rails controllers or models.
rails g react:component HelloWorld greeting:string
The generator follows standard Rails convention.
The first part
rails g
denotes we are using a rails generator.react:component
tells Rails we want to generate a new React component.In this example
HelloWorld
is the name of our component.Finally
greeting:string
tells Rails that the component should have one prop calledgreeting
that is of typestring
.
By default, components will be added to the app/javascript/components/
directory. You can also specify a subdirectory for the component to be added to instead by appending it to the component name in the generator command like so:
rails g react:component my_subdirectory/HelloWorld greeting:string
Now all that is left is to render our component in a view. For the purposes of testing everything to make sure it works, I just set my root
route to an index action within the default ApplicationController
with a matching index.html.erb
file to play around with rendering. Regardless of what view you use, rendering your component should be the same. We will use the react_component
helper in our view file like so:
<%= react_component("HelloWorld", { greeting: "Hello from react-rails." }) %>
This helper takes two arguments. The first is the name of the component we want to render as a string, the second is an object with key value pairs corresponding to prop name and values to be passed to our component. If we start our server with rails s
and navigate to whichever page we rendered our component to, we should be greeted with the message "Hello from react-rails.".
Conclusion
That's all there is to it. We now have a Rails project in which we can use React components directly in our views. There are many things we can do from here, but this setup now provides us with the ability to create and use whatever components we would like for our project.
If you'd like to get started creating your own react-rails
project check out some of the resources below:
Top comments (1)
Thanks for the write up. We might have to do a similar thing at work. The kicker is that the React app we have to include will need to be fully contained, as it also lives as a standalone React app in a node server. The React app has react-router which further complicates things.
Are there anything to worry about when deal with the fact that react-router has to coexist with Rails routing?