Using React and Rails Together
Tags: react, rails, gem
Published: 2020-11-17 02:01:07

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](https://github.com/reactjs/react-rails). 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 called `greeting` that is of type `string`. 

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:

```erb
<%= 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:

- [`react-rails` documentation](https://github.com/reactjs/react-rails)
- [Simple Rails CRUD app with React Frontend, using ‘react-rails’ gem](https://medium.com/quick-code/simple-rails-crud-app-with-react-frontend-using-react-rails-gem-b708b89a9419)
- [How To Set Up a Ruby on Rails Project with a React Frontend](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-ruby-on-rails-project-with-a-react-frontend)