React on Rails

Posted on by Chris McLean

React on Rails

Ever try writing Angular on Rails? I have and it’s nothing short of belly flopping into a pool of rusty nails and sadness.

mistake.gif

Don’t get me wrong. We love Angular here at Cloudspace and it’s our front end framework of choice for most split stack applications. However, as a light front end layer for a Rails app….no. Just no. For all the fun directives, controllers, filters, and animation helpers give you, the battle for ownership over business logic, routing, and other kinds logic becomes a fierce neverending struggle driving you closer and closer to the bar for happy hour.

All I can say is that React on Rails has made full stack development fun for me again.

Problem Space

I want to have a seamless flow of data from my models to my javascript heavy widgets with very little effort on my end.

Tools

React is as close to a web component framework as we’re going to get in modern JavaScript, alongside Polymer. It allows us to create tight JavaScript objects that represent various sub components of our applications. React however, has no support for business logic, routing, or structure.

Ruby on Rails is a full encompassing web application framework. It’s goal is to be the one platform for you application and glue together any extra components you need through the use of gems and engines. Ruby on Rails on it’s own however, is terrible at complex and highly interactive user interfaces.

Enter React-Rails

Like everything in Ruby, react-rails is just a gem. The install instructions can be found on their github page here, but they fundamentally come down to just installing a gem and running a generator. https://github.com/reactjs/react-rails

When generated, the gem adds a components directory to your assets directory and allows you to write in Facebook’s flavor of JSX. You also have access to view helpers that will render those components inline with your HAML or ERB.

A Bit on Web Components

The web component is a front end design pattern that is steadily gaining more popularity over the past few years. We saw it in it’s infancy with jQuery plugins, and saw it truly start to shine in Angular with directives, and then emerge in it’s purest essence in React and Polymer. As we speak, native web components are growing more and more support on a native level with browsers. Put it bluntly, the web component is javascript and markup that extends the normal functionality of HTML. For example, if we want a navbar on our page, a web component may look like this.

This would build a navbar contained to the custom root element that we specify. This is highly reusable, and should ideally carry very few dependencies.

The react-rails gem fully embraces the web component philosophy while at the same time, embraces web component like structures as a part of the Rails framework. They are treated as just another layer on top of models, views, and controllers. This pattern might better be thought of as Model, View, Controller, Web Component. Just promise to not abbreviate that as MVCWC. We really don’t need more acronyms.

Component Generation

You can generate a new component by just running a generator like you would a model, controller, or a migration.

This will add a new base React component in your assets directory and exposes an associated view helper.

View Helpers

What makes the gem worth while though is the view helper that let’s you easily pass data to your javascript layer as easily as including a partial.

This allows your React class to act on a new level below your view, like a directive might in Angular. This, my friends, acts like a component.

bowing-2.gif

Example Project: From Database to Graph

The following files show how we might implement a d3 bar graph detailing the number of blog posts per topic in an application. You can see how we just allow data to move in a linear fashion from the database, to the model, to the controller, to the view, and eventually to the bar graph.

The full project can be viewed here. https://github.com/cloudspace/react-rails-blogpost

Step 1: Setup

Add to your gemfile

Run

Step 2: Scaffold your Model

We don’t need anything really complex for our data layer. Really we just want the supporting elements to make a graph possible. So, we’re going to run the default scaffold for a model.

rails g scaffold Post topic:string content:string title:string

This will build our model

Step 3: Create some Seed Data

In your seeds file, you’re going to want to create a few posts to work with when we migrate the database. So, just add the following.

Step 4: Build a Method to Pull Down Data

Our graph is going to need our data in a certain format to work with. Make the Post model look like this. Since this method makes use of all of the Posts, we put it on the class level.

In our PostsController we’re also going to want to grab hold of this data from the model and pass it to the view like so.

Step 5: Generate a Component

Step 6: Building the Graph

We’re going to make the graph component look like this. Since, this isn’t a D3.JS post, I won’t go too much into how the graphing logic works, but I will point out what is custom, and what React is expecting.

React is expecting two properties in this particular object to exist, ‘propTypes’, and ‘render’. All React components are duck typed to expect a variety of different methods that hook into different steps of compilation and validation. In this case, we only care that the types that we pass in are correct and translated from Rails to JSX, as well as that we actually render the graph.

Everything else is custom to how we want our component to actually work. For example, the xScale and yScale functions just help us abstract out some of the D3 code to be a bit more readable.

Step 7: Including our component

It’s not going to look very pretty, but all we care about right now is that we can see the graph. Head over to app/posts/index.html.erb and add the following right under the h1 tag.

React-rails will handle the translation of data as it moves between languages for us. Stats is a Ruby hash, yet will be an object literal when we jump to our JSX code.

Step 8: Styling our Graph

We don’t need much style, but we do want to make sure that graph works and looks semi decent, especially since our graphing logic in the component has no styling whatsoever. Create a new sass file named chart.scss and add the following.

Conclusion?

Componentizing your front end can do wonders for your web apps, especially in a world where spaghetti jQuery runs amuck. React is just one solution, but there are several options out there that can help you achieve a similar result. I hope that next time you start a Rails app though, that you will give React, or a similar component like framework a try.

 
comments powered by Disqus