Saturday, August 6, 2016

React.js - A guide for Rails developers_part 1


Introduction to React.js

React.js is the new popular guy around the "JavaScript Frameworks" block, and it shines for its simplicity. Where other frameworks implement a complete MVC framework, we could say React only implements the V (in fact, some people replace their framework's V with React). React applications are built over 2 main principles: Components and States. Components can be made of other smaller components, built-in or custom; the State drives what the guys at Facebook call one-way reactive data flow, meaning that our UI will react to every change of state.
One of the good things about React is that it doesn't require any additional dependencies, making it pluggable with virtually any other JS library. Taking advantage of this feature, we are going to include it into our Rails stack to build a frontend-powered application, or you might say, a Rails view on steroids.

A mock expense tracking app

For this guide, we are building a small application from scratch to keep track of our expenses; each record will consist of a date, a title and an amount. A record will be treated as Credit if its amount is greater than zero, otherwise it will be treated as Debit. Here is a mockup of the project:


Summarizing, the application will behave as follows:
  • When the user creates a new record through the horizontal form, it will be appended to the records table
  • The user will be able to inline-edit any existing record
  • Clicking on any Delete button will remove the associated record from the table
  • Adding, editing or removing an existing record will update the amount boxes at the top of the page
Initializing our React.js on Rails project

First things first, we need to start our brand new Rails project, we are naming it Accounts:
  1. rails new accounts
For this project's UI, we'll be using Twitter Bootstrap. The installation process is out of the scope of this post, but you can install the bootstrap-sass official gem following the instructions from the official github repo.
Once our project has been initialized, we proceed to include React. For this post I decided to include it via the official gem react-rails because we are going to take advantage of some cool features included in this gem, but there are other ways to achieve this task, like using Rails assets or even downloading the source package from the official page and pasting it into our javascripts folder.
If you have been developing Rails apps, you know how easy it is to install a gem: Add react-rails to your Gemfile.
  1.   gem 'react-rails', '~> 1.0'
Then, (kindly) tell Rails to install the new gems:
  1.   bundle install
react-rails comes with an installation script, which will create a components.js file and a components directory under app/assets/javascripts where our React components will live.
  1.  rails g react:install
If you take a look at your application.js file after running the installer, you will notice three new lines:
  1.  //= require react
  2.   //= require react_ujs
  3.   //= require components
Basically, it includes the actual react library, the components manifest file and a kind of familiar file ended in ujs. As you might have guessed for the file's name, react-rails includes an unobtrusive JavaScript driver which will help us to mount our React components and will also handle Turbolinks events.

Creating the Resource

We are going to build a Record resource, which will include a date, a title, and an amount. Instead of using the scaffold generator, we are going to use the resource generator, as we are not going to be using all of the files and methods created by the scaffold generator. Another option might be running the scaffold generator and then proceed to delete the unused files/methods, but our project can turn a little messy after this. Inside your project, run the following command:
  1.   rails g resource Record title date:date amount:float
After some magic, we will end up with a new Record model, controller, and routes. We just need to create our database and run pending migrations.
  1.  rake db:create db:migrate
As a plus, you can create a couple of records through rails console:
  1.  Record.create title: 'Record 1', date: Date.today, amount: 500
  2.   Record.create title: 'Record 2', date: Date.today, amount: -100
Don't forget to start your server with rails s.
Done! We're ready to write some code.

Nesting Components: Listing Records

For our first task, we need to render any existing record inside a table. First of all, we need to create an index action inside of our RecordsController:
  1.   # app/controllers/records_controller.rb
  2.   class RecordsController < ApplicationController
  3.     def index
  4.       @records = Record.all
  5.     end
  6.   end
Next, we need to create a new file index.html.erb under apps/views/records/, this file will act as a bridge between our Rails app and our React Components. To achieve this task, we will use the helper method react_component, which receives the name of the React component we want to render along with the data we want to pass into it.
  1.  <%# app/views/records/index.html.erb %>
  2.   <%= react_component 'Records', { data: @records } %>
It is worth mentioning this helper is provided by the react-rails gem, if you decide to use other React integration method, this helper will not be available.
You can now navigate to localhost:3000/records. Obviously, this won't work yet because of the lack of a Records React component, but if we take a look at the generated HTML inside the browser window, we can spot something like the following code
  1.   <div data-react-class="Records" data-react-props="{...}">
  2.   </div>
With this markup present, react_ujs will detect we are trying to render a React component and will instantiate it, including the properties we sent through react_component, in our case, the contents of @records.
The time has come for us to build our First React component, inside thejavascripts/components directory, create a new file called records.js.coffee, this file will contain our Records component.
  1.  # app/assets/javascripts/components/records.js.coffee

  2.   @Records = React.createClass
  3.     render: ->
  4.       React.DOM.div
  5.         className: 'records'
  6.         React.DOM.h2
  7.           className: 'title'
  8.           'Records'
Each component requires a render method, which will be in charge of rendering the component itself. The render method should return an instance of ReactComponent, this way, when React executes a re-render, it will be performed in an optimal way (as React detects the existence of new nodes through building a virtual DOM in memory). In the snippet above we created an instance of h2, a built-in ReactComponent.
NOTE: Another way to instantiate ReactComponents inside the render method is through JSX syntax. The following snippet is equivalent to the previous one:
  1.  render: ->
  2.     `<div className="records">
  3.       <h2 className="title"> Records </h2>
  4.     </div>`
Personally, when I am working with CoffeeScript, I prefer using the React.DOM syntax over JSX because the code will arrange in a hierarchical structure by itself, similar to HAML. On the other hand, if you are trying to integrate React into an existing application built with erb, you have the option to reuse your existing erb code and convert it into JSX.
You can refresh your browser now.
Written  by Fernando Villalobos

If you found this post interesting, follow and support us.
Suggest for you:

Build Web Apps with React JS and Flux

Meteor and React for Realtime Apps

Modern React with Redux

Build Apps with React Native

The Complete Web Development Tutorial Using React and Redux

1 comment:

  1. Hi, Very informative blog.There is so much information about the ReactJS. keep it up and thanks for the great content. Bookmarked your site.
    Regards,
    Ramya,
    ReactJS Online Training in Hyderabad

    ReplyDelete