【学生限定】夜の合同説明会を開催します【クックパッドxドワンゴxグリーxはてな】

将来に悩んでいる学生のみなさん、こんばんは。成田(@mirakui)です。

11/18(金)に、ドワンゴさん、グリーさん、はてなさん、そしてクックパッドという4社の合同で「夜の合同説明会」を開催することになりました。

エンジニア志望の学生さんに向けたパネルセッションなのですが、普通とは違った趣向ですので、この4社に興味がある方はぜひご参加ください。

お申込みは下記の connpass からお願いします。

夜の合同説明会 - クックパッド, ドワンゴ, グリー, はてな - connpass

以下、このイベントがどうすごいのか説明します。

パネリストが豪華

私を始め、各社のトップエンジニアが一同に介します。このメンバーが一箇所に揃うのはめったにない機会だと思います。レジェンドの皆さんの前に私も緊張しています。

  • 司会
    • 庄司嘉織 (クックパッド株式会社 人事部長/エンジニア) @yoshiori
  • パネリスト
    • 藤本真樹 (グリー株式会社 取締役 執行役員常務 最高技術責任者) @masaki_fujimoto
    • 大西康裕 (株式会社はてな 執行役員 サービス・システム開発本部長) @yasuhiro_onishi
    • 成田一生 (クックパッド株式会社 VP of Engineering) @mirakui
    • 清水俊博 (株式会社ドワンゴ 人事部長/エンジニア) @meso

全員飲んでいる

登壇時、パネリストは皆お酒を飲んでいます。お酒を交えながら本音で語り合うイベントというのが今回の趣旨です。

その場でしか聞くことができないぶっちゃけトークが飛び出す可能性が高いです。私は色んな意味で緊張しています。

※参加者のみなさまにもお酒を振る舞うため、20歳以上限定とさせてください

気軽に質問を投げられる

申し込み時に質問を書くところがあるので、偉い人が酔っ払っていれば答えてくれるかも? というギリギリを考えて攻めてみてください。

なにが飛び出るかわかりませんが、パネリスト一同みな覚悟して望んでいます。この業界に興味のある学生の皆さんは、この機会にぜひお越しください。

お申込みはお早めにこちらまで!

夜の合同説明会 - クックパッド, ドワンゴ, グリー, はてな - connpass

非SPAなサービスにReactを導入する

投稿開発部の外村(@hokaccha)です。今回はReactについてのお話です。

ReactとSPA

最近JavaScriptやそれを取り巻くフレームワークなどの話題では、サーバ側はAPIのみを提供し、View(HTML)は全てJavaScriptで描画するような、いわゆるシングルページアプリケーション(以下SPA)についてよく語られます。

一方で、SPAを構築するにはコストがかかることも事実で、特にフロントエンドエンジニアが多くない環境では、従来通りサーバーサイドでViewを書きつつ動的な部分だけJavaScriptで処理するというアーキテクチャのほうが現実的な場合も往々にしてあります。

今回はこのような、サーバー側でHTMLを生成し、一部の動的な部分だけをReactで書くためのTipsを紹介します。

なお、基本的にサーバーサイドはRails前提ですが、RailsにおけるReactの開発環境の構築方法などについて以下の記事や資料を参照ください。

コンポーネントの例

例えばブログ記事に「いいね」が押せる機能を考えてみましょう。機能としては

  • いいねできる
  • いいねが解除できる
  • 自分がいいねしているかどうかわかる
  • いいねしているユーザー数が見れる
  • いいねユーザーの一覧がポップアップで見れる
  • ユーザー一覧は20件ごとに読み込む
  • いいね押したときにログインしてなければログインの誘導ポップアップが出る

このように、小さいコンポーネントではありますが、複数の状態や機能があり、いいねの付け外しやユーザー一覧の取得はAjaxで行う必要があります。

テンプレートをhamlやerbで書いてjQueryでDOM操作をして実現することもできそうですが、このような機能をjQueryだけでメンテナブルなコードを書くのは簡単ではないと思っています。一方Reactは宣言的で見通しのよいコードでコンポーネントを記述でき、Viewの機能のみを提供するという単機能なライブラリのため、こういった部分的に利用するケースでも導入しやいです*1

また私自身、これと同じような機能をjQueryとReactの両方で実装した経験がありますが、例えこのぐらい小さい機能であってもReactのほうが楽に実装できると感じました。サーバー側のテンプレート言語とReact側のJSXとでテンプレートの言語が分かれてしまうというデメリットはありますが、個人的にはそこを差し引いてもメリットのほうが大きいと思っています。

react-railsを使った自動マウント

このようにReactを動的なコンポーネントだけに使っていくという手法の場合、面倒なのがReactコンポーネントのマウントです。SPAの場合は基本的にルートコンポーネント一つをマウントすれば済みますが、こういった構成の場合は1ページに複数のコンポーネントをマウントするケースが多くなります。

例えばブログ記事のページで、いいねとコメントの2つの動的なコンポーネントがあるとします。まずはテンプレートを次のようにして

<h1><%= @entry.title %></h1>
<%= @entry.body %>

<div class="like-component"></div>
<div class="comment-component"></div>

JavaScript側で対象のDOM要素に作成したReactコンポーネントをマウントします。

document.addEventListener('DOMContentLoaded', () => {
  let like = document.querySelector('like-component');
  let comment = document.querySelector('comment-component');

  ReactDOM.render(React.createElement(LikeComponent), like);
  ReactDOM.render(React.createElement(CommentComponent), comment);
});

2つくらいであればこれでもいいですが、コンポーネントを作る度にこのようなコードを書かないといけないのは面倒です。また、コンポーネントの初期値としてpropsを与えたいというケースも出てくるでしょう。

そこでRailsの場合はreact-railsを使うのがオススメです。react-railsにはサーバーサイドレンダリングなどの興味深い機能もありますが、今回はview helperとreact_ujsを使った自動マウントの機能を紹介します。

先程の例はreact-railsを使うと次のように書くことができます。

<h1><%= @entry.title %></h1>
<%= @entry.body %>

<%= react_component('LikeComponent') %>
<%= react_component('CommentComponent') %>

JavaScript側ではreact_ujsを読み込んでおき、コンポーネントをグローバルから参照できるようにしておくだけで自動的にコンポーネントがマウントされます。

また、引数でpropsを渡すこともできます。

<%= react_component('LikeComponent', liked: @current_user.liked?(@entry), likeCount: @entry.likes.count) %>

このようにすることでLikeComponentに初期値をpropsとして渡すことができ、Ajaxで通信せずとも初期描画を行うことができます。

また、react_ujsの自動マウントはturbolinksにも対応しており、turbolinksでページ遷移したときに自動でマウント・アンマウントを行ってくれるという機能があります。jQuery時代にturbolinksを使って$(document).ready()が走らなくてハマる、という経験されたことがある方には嬉しいかもしれません。

Railsを使わない場合や、それだけのためにreact-railsを使いたくない場合は同じような仕組みを実現するのは大した手間ではないので自作してもいいと思いますが、1ページに複数コンポーネントをマウントする場合は、何かしらこのような自動マウントの仕組みがあると便利です。

react-micro-container

Reactではルートコンポーネントが全ての状態を管理し、子のコンポーネントにはpropsとして値を渡すようにすることで、できるだけコンポーネントから状態を取り除くというプラクティスがあります。このとき子要素で発生したイベントをルートコンポーネントに伝える手段が必要になります。

愚直にやるとイベントハンドラを子要素に渡し、全てのコンポーネントでイベントを拾って一つ上の親にあげていくという処理が必要になります。例えば、いいねコンポーネントで、「いいね」や「もっと見る」を押したときのイベントをルートコンポーネントまで伝えるのは次のようなイメージです*2

f:id:hokaccha:20161026134922p:plain

これがいわゆるイベントのバケツリレーです。今回のような小さいコンポーネントの場合も、内部でコンポーネントを分割していくと容易に数段のネストしたコンポーネントになります。

何かしらのFluxフレームワークを使ってもよいですが、こういった小さいコンポーネントにFluxフレームワークはオーバースペックなことも多いです。そこで拙作ですが、react-micro-containerという小さいライブラリを使うと、イベントのバケツリレーだけを簡略することができます。

f:id:hokaccha:20161026134928p:plain

個人的には小さいコンポーネントではこれぐらいで十分なケースも多いと思っています。詳しい使い方などはこちらの記事を参照してみてください。

小さいReactアプリケーションのためのライブラリ書いた - Qiita

注意点として、これは小さいコンポーネントであればうまくいきますが、規模が大きくなってくるとイベントの数が多くなりすぎて破綻してくるので、そういった場合はFluxフレームワークを導入するなどの対応が必要になるかもしれません。

まとめ

サーバー側で静的なHTMLを出力しつつ、動的にしたい部分だけをReactを使って実装する際のTipsについて紹介しました。

ReactはFluxなどを使って大きいアプリケーションを作ろうとすると、とたんに設計が難しくなってきますが*3、こういった小さいコンポーネントから導入する方法であれば、JavaScriptの設計になれていなくても導入しやすいですし、現状のアプリケーションに一部分導入するということも可能です。

Reactに興味はあるが難しそうで二の足を踏んでいるという方はこのようなところから利用してみてはいかがでしょうか。

*1:PolymerやVue.jsも同じようなことが実現できそうですが今回はReactにフォーカスしています

*2:コンポーネントのツリーはわかりやすくするために簡略化しています

*3:Reactに限った話しではなく、規模が大きくなれば何を使っても難しくなります

来年も Cookpad TechConf やります

こんにちは! @yoshiori です。

今年年明けに Cookpad TechConf 2016 という、クックパッドのエンジニア、デザイナーがサービスづくりの過程で得た技術的知見や経験をみなさんに発表させていただくイベントを開催させていただきました。
こういったイベントは続けてナンボ!!! ってことで来年もやります!!!
前回は会場キャパシティ 250 人の所、1000 人以上のお申込みを頂きました。
今回はその反省も含めレイアウトを変更し会場キャパシティ 350 人用意しました!!!

今年もエンジニア組織的な話から海外展開で得た知見、基盤技術、サービス開発、デザイン、機械学習など多種多様なコンテンツを用意していますので、知っている分野は更に知見が深まり、知らない分野のこともザックリ知れる。そんな一日にしたいと思っています。

一同お待ちしています! みなさま奮ってご参加ください!

Cookpad TechConf 2017

タイムテーブル

タイトル 発表者
Cookpad under a microscope 成田 一生
Deliver apps to global audience 滝口 健太郎
Building infrastructure for our global service sorah
クックパッドで取り組めるデザイン(仮) 若月 啓聡
モバイルアプリのA/Bテスト基盤 加藤 龍
チームでサービス開発をするための取り組み 丸山 亮
サービスのプロトタイピング時に心がけていること(仮) 須藤 耕平
フェージングのすゝめ 〜サービスの大規模リニューアルの話〜(仮) 京和 崇行
快適なサービス開発を支える技術 国分 崇志
Real World Machine Learning 染谷 悠一郎
行動ログでプロダクトを改善するには 兼山 元太
Cookpad awakens 庄司 嘉織

お申込み

お申込みはコチラ から