react(flex)와 rails(turbolinks)의 친화성

1. 개요


이 보도는 25일째 투고한 것이다.
react(flex)와 rails(turbolinks)를 조합하면 어떤 장점이 있는지 쓰고 싶습니다.
요컨대, 이 글은 여러 페이지가 관련되어 있는데,react의 장점을 어떻게 활용하는가에 관한 것이다.

2.turbolinks


turbolinks는 aax를 사용하여 페이지 이동을 하는 기능으로 Rails4에서 기본적으로 탑재됩니다.
동작으로, js와 css를 다시 가져오지 않고, aax에서 DOM을 업데이트합니다.
이 기능도 여러 가지 문제가 발생할 수 있다(예를 들어 트위터의widget은 불이 나지 않는다는 등).react(flex)와 매우 일치하는 기능이다.
flumx를 사용하면 aax(fetch)에서 얻은 데이터는 Store에 저장되어 이를 바탕으로 그려지기 때문에 페이지가 이동할 때 js를 다시 읽지 않는 것이 좋습니다.
이것은 js가 미리 컴파일되어 하나의 파일 (어느 페이지든 마찬가지) 이 되는 것을 전제로 하지만, rails의 경우 이렇다.
자세한 내용을 알고 싶으신 분들은 아래 기사를 참고하시기 바랍니다.
  • Qiita React.js Advent Calendar 2015
  • Rails4에서 Turbolinks를 구가하기 위한 총결산
  • 3. 구체적으로 하고 싶은 일


    내가 구체적으로 하고 싶은 것은 스토어의 정보를 유지하여 페이지를 이전하는 것이다.
    통상적으로 React-router를 사용하지만, rails 기본 터보링크스를 사용하면 같은 일을 할 수 있습니다.
    어느 페이지에서든 웹 페이지에 필요한 내용을 Store에 비동기적으로 저장합니다.
    사용자가 페이지를 이동하는 시간에 대해 불만을 느끼지 않는 것은 내가 하고 싶은 일이다.
    예를 들어 컨트롤러 측에서 1000ms의 무거운 페이지를 처리해야 한다면, 미리 다른 방식으로 불러오고,render 원가만 제어합니다.
    무거운 페이지를 처음 열면 어쩔 수 없지만, 꼭대기에서 무거운 페이지로 이동하는 데 도움이 될 것 같습니다.

    4. TODO App


    실제로 간단한 토도 앱을 제작했다.
    Rails4의 Turbolinks에 대해서 가장 궁금한 게 있어요.
    fetch GET의 todos에 있습니다.제이슨이 상점에 데이터를 저장하는 곳입니다.
    첫 페이지에 불러오는 것을 제외하고는 일람표를 얻지 못한 것을 보기 어렵지만, 나는 알아야 한다고 생각한다.
    이렇게 터보링크스를 능숙하게 사용하면 API 두드리는 양을 줄일 수 있어 좋다.
    이 앱은 TODO의 state가 비어 있을 때만 현재의 모든 TODO를 얻을 수 있고 그 외에 다시 가져오지 않습니다.
    TodoActionCreators.fetch() if Object.keys(@state.todos).length is 0
    
    이용의 주요gem는,
  • react-rails
  • bower-rails
  • sprockets-coffee-react
  • 3점.

    react-rails


    rails에서react를 사용할 때 편리한gem입니다.
    서버 측에서prerender를 사용할 수도 있고 <=> 캐러멜의 변수 이름 변환, 개발자/production 모드 등을 호출할 수도 있습니다.

    bower-rails


    프론트 데스크 시스템 라이브러리 관리를 맡다.
    rails-assets와 달리 선행 시스템 라이브러리에서 이미지를 사용하는 경우도 지원합니다.
    제품에 따라 bower-rails를 이용하는 것이 선택이라고 생각합니다.
    이번에는 flumx와 이벤트mitter를 설치하는 데 사용합니다.

    sprockets-coffee-react


    cjsx로react를 쓴gem입니다.
    jsx를 직접 쓰고 싶은 사람은 필요 없을 수도 있습니다.
    기본적으로coffeescript의 대응도 있지만,render 부분은
      render: ->
        `<div></div>`
    
    이렇게 하려면 반드시 '둘러야 한다. 매우 번거롭기 때문에 사용하고 있다.

    5. 다양한 환경 준비


    Rails 4.2.5, Ruby 2.2.3 환경 준비
    우선 rails new를 정리한 후 창고 주위의 준비를 잘 하세요.
    rails new flux-rails -T --skip-bundle
    vim Gemfile
    
    Gemfile을 열면 다음 4개를 추가합니다.
    슬림 이외의 템플릿 엔진을 사용하고 싶으신 분들은 적당히 교체해 주십시오.
    gem 'react-rails'
    gem 'sprockets-coffee-react'
    gem 'bower-rails'
    gem 'slim-rails'
    
    추가해서 bundle install 입니다.
    bundle install -j4 --path vendor/bundle
    
    다음은 선행 시스템 라이브러리를 준비합니다.
    rails g bower_rails:initialize
    vim Bowerfile
    
    Bowerfile에 flex와 eventemiter를 추가합니다.
    레드ux 등도 있지만 정식flux를 이용하고 있습니다.
    이번에는 이벤트미터2를 이용해서
    asset 'flux'
    asset 'eventemitter2'
    
    설치 완료rake bower:install마지막으로 js 파일을 읽습니다.
    터보링크 다음에 쓰지 않으면 페이지를 변환할 때react시스템을 제대로 불러올 수 없습니다.
    app/assets/javascripts/application.js
    //= require jquery
    //= require jquery_ujs
    //= require turbolinks
    //= require react
    //= require react_ujs
    //= require flux/dist/Flux
    //= require eventemitter2/lib/eventemitter2
    //= require_tree ./constants
    //= require_tree ./dispatcher
    //= require_tree ./actions
    //= require_tree ./stores
    //= require_tree ./components
    
    require_tree에 디렉터리가 없으면 오류가 발생하기 때문에 디렉터리로 만듭니다.
    cd app/assets/javascripts/
    mkdir constants
    mkdir dispatcher
    mkdir actions
    mkdir stores
    mkdir components
    
    이렇게 환경 구축이 끝난다.
    그리고 react 쓸 때처럼 기술하면 돼.

    6.react-rails가 이용하는 것


    component 게시


    보통 렌더는...
    = react_component('HelloMessage', {name: 'John'})
    
    서버 쪽에서 렌더링을 하고 싶은 건 이런 느낌이에요.
    = react_component('HelloMessage', {name: 'John'}, {prerender: true})
    
    name: 'John'는 다양한 전문성입니다.
    여기에서 렌더링, 클라스 이름이 무엇인지 지정할 수 있습니다.

    변수 이름을 낙타<=> 뱀으로 변환

    config/application.rb에 미리 기술한 경우config.react.camelize_props = true,
    자동으로 낙타<=> 뱀의 변수 이름을 변환합니다.todo_id: 4를 프롭스에 건네면 @props.todoId => 4 느낌이 들어 소박하고 편리해요.

    controller render

    class TodoController < ApplicationController
      def index
        @todos = Todo.all
        render component: 'TodoList', props: { todos: @todos }, tag: 'span', class: 'todo'
      end
    end
    
    컨트롤러 쪽에서도 서버 쪽에서rendering을 할 수 있다.
    또 자기가 커피로 썼기 때문에 잘 모르겠어요. ES6로도 쓸 수 있을 것 같아요.

    7. 요약

  • turbolinks를 사용하면 rails의 rails를 탑승한 상태에서react(flex)
  • 를 이용할 수 있다.
  • react-rails 편리
  • 좋은 웹페이지 즐겨찾기