ReactJs với Rails

Nội Dung

  1. ReactJs là gì?
  2. Một số cách tích hợp ReactJs vào Rails
  3. Các bước xây dựng ứng dựng web đơn giản ReactJs với Rails

ReactJs là gì ?

  • Reactjs là một thư viện JavaScript tạo ra bởi Facebook
  • Khái niện trên trang web chính thức 'A JavaScript library for building user interface' ,là một thư viện sinh ra để xây dựng giao diện người dùng(UI). Nó không phải framework mà chỉ là thư viện, và trong mô hình MVC nó tương ứng với phần V.
  • Facebook, Instagram, Yahoo hay Airbnb đều dùng ReactJS , hiện nay đây là thư viện được quan tâm nhiều.

Cơ chế hoạt động của ReactJS

  • React sử dụng cơ chế one-way data binding - luồng dữ liệu một chiều.Dữ liệu được truyền từ parent đến child thông qua props.

Virtual DOM

  • Virtual Dom là công nghệ Dom ảo được React sử dụng để tối ưu Update Ui khi có sự thay đổi về dữ liệu. Có thể hiểu Virtual Dom là bản sao Dom. Khi ứng dụng hoạt động thì các thay đổi trên Dom sẽ được tính toán trước trên Dom ảo, phân tích tối ưu rồi mới update Dom. => Tăng hiệu suất ứng dụng.

Ưu điểm

  • Luôn biết được component của bạn sẽ sinh ra mã HTML như thế nào chỉ bằng cách nhìn vào file source code.
  • Render React phía server
  • ReactJS tạo ra DOM ảo nơi mà chứa các component và React tính toán những cập nhập rồi thực hiện thay đổi lên DOM, điều đóa thực sự hiệu quả.
  • ReactJS giúp việc code JS trở lên dễ dàng hơn với JSX.

Khuyết điểm

  • ReactJs chỉ vục phụ tầng view
  • Tích hợp vào MVC truyền thống cần tích hợp lại
  • Khó học đối với người mới học web
  • Tài liệu nghèo nàn
  • Khá nặng so với framework khác

Một số thành phần trong ReactJS

Props

  • Được sử dụng để truyền dữ liệu vào trong React view, bất kì có sự thay đổi nào thì props sẽ được kích hoạt tự động đối với cả thành phần cha và con
var HelloWorld = React.createClass({
    render: function() {
        return <div>Hello! {this.props.name}!</div>;
    }
});
React.render(<HelloWorld name='Teo'/>,document.body);
  • Name 'Teo' sẽ được in ra màn hình
Hello! Teo!

State

  • Thuộc tính state của React class cho phép chúng ta theo dõi được sự thay đổi trong view.
  • Nó cũng như props cũng sẽ tự động kích hoạt render view khi mà state thay đổi với điều kiện phải gọi method setState.
  • Phải sử dụng fuction getInitialState để khởi tạo state để view biết được state khởi tạo với giá trị nào.
getInitialState: function() {
        return {
            counter: 10
        };
    }

Component

  • React được xây dựng xung quanh các component, chúng ta có thể tái sử dụng component ở nhiều nơi với các trạng thái và thuộc tính khác nhau, trong một component lại chứa một thành phần khác.Mỗi conponent có một trạng thái riêng có thể thay đổi và thực hiện cập nhật dựa trên trạng thái đóa.
  • Component là thành phần rất quan trọng React

React Component LifeCycle

  1. Initialization Phương thức getInitialState giúp ta khởi tạo giá trị ban đầu của state, và có thể truy cập bên trong component thông qua this.state getInitialState: function(){ return { /* something here */}; } Phương thức getDefaultProps dùng để khai bảo khởi tạo bất kỳ một props nào, và cũng được gọi thông qua this.props getDefaultProps: function(){ return { /* something here */}; } 2.State Changes 3.Props Changes

Hàm và phương thức của Component

  • Constructor(props) :Thực hiện thiết lập state và sử dụng super(props) để có thể sử dụng được props trong component.
  • componentWillMount():Thực hiện một số tác vụ, gọi một lần trên cả server lẫn client trước khi render diễn ra.
  • componentDidMount(): Thực hiện một số tác vụ, được gọi một lần client sau render.
  • componentWillUnmount():Thực hiện một lần duy nhất, khi component sẽ unmount, được gọi trước khi tách component.
  • componentWillReceiveProps(nextProps) :Hàm này thực hiện liên tục mỗi khi props thay đổi.
  • shouldComponentUpdate(nextProps, nextState) :Thực hiện khi state và props thay đổi.

Tích hợp ReactJS vào Rails

  1. Sử dụng gem react-rails Sử dụng gem react-rails là một cách đơn giản nhất và nhanh nhất để có thể sử dụng react trong rails. Nó sử dụng quản lý asset mặc định của Rails và tự động chuyển JSX thành asset pipeline sử dụng Ruby Babel .
  2. Rails API và React fontend Ở đây sử dụng Rails như là một back-end và React như là một font-end và là 2 ứng dụng khác nhau.Mình thấy cách này khá trong sáng, rõ ràng và rất hiệu quả nhưng phức tạp.

Xây dựng ứng dụng web đơn giản với ReactJS và Rails

  1. Tạo mới ứng dụng sử dụng terminal rails new People-Lecture
  2. Cài đặt gem để có thể sử dụng React on rails gem "react-rails"
  3. Tạo model person với các thuộc tính như sau:
class CreatePeople < ActiveRecord::Migration[5.0]
  def change
    create_table :people do |t|
      t.string :first_name
      t.string :last_name
      t.integer :gender
      t.date :birth_date
      t.string :location
      t.string :email
      t.text :headline
      t.string :image
      t.string :phone

      t.timestamps
    end
  end
end
  1. Tạo controller Home làm trang chủ của website
class HomeController < ApplicationController
  def index
  end
end

  1. Tạo controller People để lấy dữ liệu về people và trả về dưới dạng json
class PeopleController < ApplicationController
  before_action :search_people

  def index
    render json: { people: @people}
  end

  private

  def search_people
    @people = Person.search params[:q]
  end
end

  1. Trong model Person viết method search để tìm kiếm person
class Person < ApplicationRecord
  scope :search, ->q do
    where "first_name LIKE ? OR last_name LIKE ? OR email LIKE ?", "%#{q}%", "%#{q}%", "%#{q}%" if q.present?
  end
end

  1. Trong /views/home/ tạo index.html.erb tương ứng với controller HomeController.Sửa dụng react_compenent để render component có tên là People vào file này.
<div class="container">
  <div class="row">
    <h1 class="title">ReactJS in Rails</h1>
  </div>
  <div class="row">
    <%= react_component "People",{} %>
  </div>
</div>
  1. Trong assets/javascripts/components/ tạo file people.js.jsx dùng để khởi tạo people và lấy dữ liệu từ controller People và render ra view.
var People = React.createClass({
  getInitialState: function(){
    return{
      people: [],
      didFetchData: false
    }
  },
  fetchDataDone: function(data){
    this.setState({
      people: data,
      didFetchData: true
    })
    console.log(this.state.people);
  },
  handleOnSearchSubmit: function(search){
    $.ajax({
      url: Routes.people_path(),
      dataType: 'json',
      data:{q: search},
      success: function(data){
       this.fetchDataDone(data);
      }.bind(this),
      error: function(xhr, status, err){
        console.error(Routes.people_path(), status, err.toString());
      }
    })
  },
  componentDidMount: function(){
    $.ajax({
      url: Routes.people_path(),
      dataType: 'json',
      success: function(data){
       this.fetchDataDone(data);
      }.bind(this),
      error: function(xhr, status, err){
        console.error(Routes.people_path(), status, err.toString());
      }
    })
  },
  render: function(){
    let arr = $.map(this.state.people, function (value,index) { return value; });
    console.log(arr)
    var personNote = arr.map(function(person,index) {
      return <Person data={person} key={index} />
    });
    let kq;
    if(arr.length > 0){
      kq=(
       <div>
          {personNote}
       </div>
      )
    }else if(this.state.didFetchData)  {
      kq = (
        <div className = 'alert alert-warning'>
          <h4>Not found people</h4>
        </div>
      )
    }else {
      kq=(
       <div>
          {personNote}
       </div>
      )
    }
    return(
      <div className = 'mainContainer'>
        <div className = 'row'>
          <PeopleSearch onFormSubmit={this.handleOnSearchSubmit} />
        </div>
        <div>
          {kq}
        </div>
      </div>
    )
  }
})

  • getInitialState(): khởi tạo state cho component People
  • componentDidMount(): Được gọi lên server sau khi render html để lấy dữ liệu về people.
  • fetchDataDone(): Khi mà ajax thành công thì sẽ setState ở function này để cập nhật dữ liệu cho component.
  1. Trong assets/javascripts/components/ tạo file person.js.jsx dùng để show từng item của people
var Person = React.createClass({
  render: function(){
    return(
      <div className='col-md-4'>
        <div className='card'>
          <div className='card-header'>
            <div className='col-md-4 avatar'>
              <img className="img" src={this.props.data.image} />
            </div>
            <div className='col-md-8 info'>
              <h4><span>{this.props.data.last_name}</span></h4>
              <ul>
                <li>
                  <i className='fa fa-map-marker'>
                  </i>
                  <span>{this.props.data.location}</span>
                </li>
                <li>
                  <i className='fa fa-birthday-cake'>
                  </i>
                  <span>{this.props.data.birth_date}</span>
                </li>
              </ul>
            </div>
          </div>
          <div className='card-body'>
            <div className='headline'>{this.props.data.headline}.</div>
            <ul className='contact-info'>
              <li>
                <i className='fa fa-phone'></i>
                <span>{this.props.data.phone}</span>
              </li>
              <li>
                <i className='fa fa-envelope'></i>
                <span value={this.props.data.id}>{this.props.data.email}</span>
              </li>
            </ul>
          </div>
        </div>
      </div>
    )
  }
})
  1. Kết quả đạt được

Link demo

  1. Link demo
  2. Source code tại đây

Tài liệu tham khảo

1:https://learnetto.com/blog/3-ways-to-use-react-with-ruby-on-rails-5
2:https://viblo.asia/khanhhd/posts/lA7GKnpoMKZQ
3:https://viblo.asia/khanhhd/posts/pVYRPjL6G4ng
4:https://viblo.asia/NguyenThaiSon/posts/WEMkBpjDGQK
5:https://viblo.asia/pham.viet.anh/posts/157G5oaORAje
6:https://viblo.asia/norin/posts/3ZabG9pYMzY6
7:https://facebook.github.io/react/
8:https://coddingdaily.blogspot.com/2015/06/reactjs-bai-5-state-la-gi.html
9:https://kipalog.com/posts/Hoc-ReactJS-trong-15-phut--Phan-1
10:https://hpphat.wordpress.com/2017/01/03/uu-va-khuyet-diem-cua-reactjs/
11:http://codeloveandboards.com/blog/2014/09/10/rails-and-react-ii-a-real-use-case/
12:https://viblo.asia/bui.thi.huyen/posts/bxjvZYpBkJZ
13:http://blog.ows.vn/so-luoc-ve-reactjs/

ES6
1:https://ponyfoo.com/articles/es6-destructuring-in-depth
2:https://techmaster.vn/posts/34069/10-tinh-nang-cua-es6-ecmascript2015-moi-lap-trinh-javascript-phai-biet
3:http://ccoenraets.github.io/es6-tutorial-react/es6-features/