20
The First React on Rails 2016/2/19 @khrtz

The First React on Rails

Embed Size (px)

Citation preview

Page 1: The First React on Rails

The First React on Rails2016/2/19 @khrtz

Page 2: The First React on Rails

伊藤晃平

職業 Web Engineer

業務内容は主にグロースハックとかフロントエンドアイコン定まらん

UI 作ったり、 AB テストしたり、 Ruby 書いたり、 Rails の View 作ったり

Twitter @khrtz

自己紹介

アイコンと名前はころころ変わる

Web サービスを運営している会社に所属

雑兵 meetup 参加は 2 回目で LT2 回目

Page 3: The First React on Rails

今回の内容

Rails に React を導入するまでの記事はたくさんあるやってみた記事はたくさん溢れているけど、実際に運用してみた情報があまりないのでまとめてみた

現在運用している Rails アプリケーションに React.js を導入してみたので、溜まった知見を少し

実際に運用しているコードを参考に説明していきます

React.jsJUST THE UI VirtualDOM DATA FLOW

Page 4: The First React on Rails

JS Framework を導入した理由スマホの EC 購入って使いづらいという意識を変えたいWeb ページからの脱却jQuery が複雑。もう再利用できない状態で管理もできていない。泣きながら書いてる

Page 5: The First React on Rails

React にした理由

・ View レイヤーだけ扱う

・サーバーサイドレンダリングに対応 (SEO のため、ユーザーを待たせたくない場面 )

・ Admin の管理画面について Angular2.0( 今は時期が悪い ) 、 Ember.js など検討中 ( 今は jQuery)

・書きたいから・フレームワークのなかでも安定している

・腐ったらすぐ捨てられるし、気楽に入れた

・エンドユーザー向けページにおいて、データを渡せば描画できるReact 一択

Page 6: The First React on Rails

アイコン定まらん

運用している Rails アプリケーションに React.js を導入するにあたって・ SPA 化は諦める

・とりあえず Ruby で出力している HTMLを JavaScript で書き換えることを考える

・ Flux は使わない

・ Rails がある程度わかってないと苦しい・ react-rails を使う・ ReactRouter を無理に導入しようとしない

Page 7: The First React on Rails

運営しているサービスのデザインをリニューアルするついでに React にした

実験のためとりあえずスマホサイトだけ (7 割くらいは React に書き換えた )

問題は特に起こってない。 PC でも React 読み込ませているんだけどエラーは見られない (polyfill はいれてる )

まだ ES2015 の機能しか使ってない

in progress

ページングもまだ未実装簡単な stateless くらいしかしてない

ほとんど jQuery 書かなくて済んだのは良かった

Page 8: The First React on Rails

ルートディレクトリに /client を作り、 client/react-client/src/component/*.js のようなコンポーネント群を作っていく

client/react-client/src/ClientGlobal.js をエンドポイントとして、グローバル変数を管理import Items from ‘./comnents/items.js’import CommentPage from './container/CommentPage'

window.Items = Itemwindow.CommentPage = CommentPage

React

Page 9: The First React on Rails

gulp.task('compile-es6', function() {var files;files = glob.sync('./client/react-client/src/ClientGlobal.js');

return browserify({entries: files, debug: true}).transform('babelify').bundle().pipe(source('bundle.js')).pipe(gulp.dest('app/assets/javascripts/components'));

});

import CommentPage from './container/CommentPage'window.CommentPage = CommentPage

ClientGlobal.js

gulpfile.js

Page 10: The First React on Rails

react-client/src/container/CommentPage.js

import React from 'react'import Comment from '../components/comment.js'

export default class CommentPage extends React.Component { render () {

var commentsNodes = this.props.comments.map(( comment, i) => { return(<Comment comment={comment} key={i}></Comment>) }.bind(this));

return ( <div> {commentsNodes} </div> ); }}

Page 11: The First React on Rails

react-client/src/components/Comment.js

import React from ‘react'

export default class Comment extends React.Component { render() { return( <section className="comment Project-cheer"> <h1 className="u-d_none"> コメント </h1> <article className="Project-cheer__comment Media"> <div className="Project-cheer__comment-img Media__img"> <img className="Project-cheer__comment-img-prop" src={this.props.comment.profile_image} width="20" height="20" alt={this.props.comment.user.name} /> </div> <div className="Project-cheer__comment-main Media__body"> <header className="Project-cheer__comment-header u-clrfix"> <h1 className="Project-cheer__comment-name u-d_ib"><b className="u-em">{this.props.comment.user.name}</b> さん </h1> <time className="Project-cheer__comment-date">{this.props.comment.days}</time> </header> <div className="Project-cheer__comment-body"> <p>{this.props.comment.body}</p> </div> </div> </article> </section> ); }}

Page 12: The First React on Rails

<%= react_component(‘CommentPage', render(template: '/projects/comments.json.jbuilder'), {prerender: false}) %>

comments_smart_phone.html.erb

json.comments do json.partial! partial: 'comments', collection: @items, as: :itemend

comments.json.jbuilder

Page 13: The First React on Rails

_comment.json.jbuilder

json.cache! [item], expires_in: 1.hours do json.days item.reserved_at.strftime('%Y 年 %m 月 %d 日 ') if item.user.is_deleted? nil else json.user_link user_path(item.user) end

json.profile_image asset_url item.user.my_image_url

json.user item.user, :name

if item.comment.present? json.body item.comment else json.body " 頑張ってください!! " endend

partial

Page 14: The First React on Rails

_comment.json.jbuilder json.comments do

json.partial! partial: 'comments', collection: @orders, as: :orderend

Page 15: The First React on Rails

DHH Say

Page 16: The First React on Rails
Page 17: The First React on Rails

Rails 5 featureActionCableリアルタイム通信を標準で装備React × ActionCable を使ったリアルタイムチャットアプリ、 Twitter みたいな通知機能などを搭載したサービスが増える

Turbolinks3部分的な更新ができるようにやってることは大体 React

RailsAPI

バックエンドと React を切り離した Rails + React + Flux の SPA アプリが作りやすく

rails-api が標準搭載

Page 18: The First React on Rails

React 導入してみて

土台を作ってからは、 React 、 ES6 書くの楽しい。 statelessなコンポーネントをたくさん作っていきたい

でも…

Page 19: The First React on Rails

墓場にならないように、ここから抜けだしてやるという強い意思が必要

Rails はフロントエンドエンジニアにとっての牢獄

Page 20: The First React on Rails

ありがとうございましたEnjoy! JavaScript