今からでも遅くない! React事始め

  • View
    3.217

  • Download
    6

  • Category

    Software

Preview:

Citation preview

いまからでも遅くない ! React 事始め

2015/6/6@ynaruc

自己紹介

• 名前 : 成田 幸紀 ( なるた ゆきのり ) @ynaruc• 出身 : 愛媛• サイボウズ株式会社 3 年目• 松山開発部 PG

• 使っている言語• TypeScript, JavaScript, C++, etc.

勉強会やハッカソンなどのイベントが好きで,愛媛のイベントにたまに出没しています。

さっそくですが,React はご存知ですか?

React

•UI を構築するためのJavaScript ライブラリ•Facebook 製

流行っているらしい

• Fluent 2015 でも多数セッションがあった• O’reilly で入門書が発売された• 入門 React

• 採用実績もある• Facebook• Yahoo• atom

• Web に React を扱った記事が増えている

流行に乗って React に入門しよう!

今回発表すること

•React ってなんだろう•React で書くコンポーネント•簡単なアプリを書いてみる•React を書くときに便利なツール

今回発表しないこと

•テスト•仮想 DOM の詳細•サーバサイドレンダリング•Flux

入門なので詳しい方ごめんなさい

Info

•もし発表中に React を書いてみたいという方は JSFiddle で簡単に試せるので下記のリンク先でお試しください• https://goo.gl/Fp9NLj

React ってなんだろう?

React

•Facebook 製•Web アプリケーションの UI を構築するための JavaScript ライブラリ•MVC の View の役割を担当する

簡単にいうと,「 DOM の更新」と「イベントハンドリング」をやってくれる

ライブラリ

React の特徴

•役割が View だけ

•仮想 DOM

•コンポーネント

役割が View だけ

•React は MVC の View の役割

•既存の MVC フレームワークの View だけ React にすることも可能

•できることが限られているのでシンプルで覚えやすい

仮想 DOM

•React では DOM の更新に仮想 DOM を使っている

•仮想 DOM は更新が必要な箇所を自動的に計算して実際の DOM を更新する

•無駄な再描画を抑えることができる

コンポーネント

•React ではコンポーネントという単位で UI パーツを作る•コンポーネントは, UI パーツのロジックとマークアップが一箇所に定義されたもの

コメントのリストを表示する例

コメントのリストを表示する例

画面を構成するパーツはだいたいコンポーネント

コンポーネント単位で分割するメリット

•UI パーツ毎に分割できるので再利用性の高いパーツが作れる•コンポーネントの処理はコンポーネント内に閉じ込めることができる

とりあえず React で書いたコンポーネントを見てみよう!

React で Hello World

var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; }}); React.render(<Hello name="World" />, document.getElementById('container'));

React で Hello World

var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; }}); React.render(<Hello name="World" />, document.getElementById('container'));

JavaScript の中にタグがある !?

タグを使って書いているのなに?

• JSX (JavaScript XML)•コンポーネントのマークアップを書くためのシンタックス•HTML によく似ている•コンパイルすると JavaScript になる

JSX の書き方

• 基本的には HTML と似ている• JavaScript の値を使いたいときは {} で囲

む• {} の中身は JavaScript の式として

解釈されるので変数だけでなく関数も使える

<h1>{title}</h1><h1>{['hello', 'world'].join(' ')}</h1>

JSX の注意点

•HTML に似ているが属性名などは異なる場合があるので気をつける必要がある•HTML の class• JSX では className

•HTML の for• JSX では htmlFor

JSX に対する批判

• JavaScript の中にマークアップが混在している

React は JSX を使わなくても書ける

JSX のいいところ

•HTML と似ているので理解しやすい• デザイナーも理解しやすいはず

•コンポーネントの構造が分かりやすい

•React の API を隠蔽してくれる• React 側で API が変更された場合は,

コンパイラが勝手に変更してくれる

JSX で書いた例

<div> <form className="comment-form" onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} /> <input type="submit" value="add" /> </form> <CommentList comments={this.state.comments} /></div>

JavaScript で書いた例

React.createElement("div", null, React.createElement("form", { className: "comment-form", onSubmit: this.handleSubmit}, React.createElement("input", { type: "text", value: this.state.inputValue, onChange: this.handleChange}), React.createElement("input”, {type: "submit", value: "add"} ) ), React.createElement(CommentList, {comments: this.state.comments}) ) );}

JSX は使うべきか?

• JavaScript にマークアップが混在することがどうしても許せない場合は無理に使わなくても良い•個人的には JSX で書いたほうが見やすいので JSX を使うのをお勧め

今回の発表中は JSX を使ってサンプルを書きますのでご了承ください

JSX を理解した上でもう一度 Hello World

var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; }}); React.render(<Hello name=“World” />,     document.getElementById('container'));

コンポーネントの定義部分

JSX を理解した上でもう一度 Hello World

var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; }}); React.render(<Hello name=“World” />,     document.getElementById('container'));

ここでマークアップを返す

JSX を理解した上でもう一度 Hello World

var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; }}); React.render(<Hello name=“World” />,     document.getElementById('container'));

コンポーネントに渡された値は this.props で参照できる

JSX を理解した上でもう一度 Hello World

var Hello = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; }}); React.render(<Hello name=“World” />,     document.getElementById('container'));

Hello コンポーネントを id=“container” な要素に描画

Hello World の学び

•コンポーネントの作り方•React.createClass を使って作る•コンポーネントの DOM 構造はrender 関数で返す

•React.reander を使って指定した要素にコンポーネントを描画する

簡単なコンポーネントの作り方は分かったので,簡単なアプリを

作ってみよう!

サンプルコード

JSFiddle にありますhttp://goo.gl/n1944d

作るアプリ

【機能】テキスト入力欄にコメントを入力して「 add 」を押すとコメントがリストに追加される

作るコンポーネント

CommentApp コンポーネント

CommentList コンポーネント

まずは CommentList から

•CommentApp からコメントの配列を受け取ってリストを表示する

•渡されるコメントの配列は以下の様な形式• [“ こんにちは” , “ プロ生ちゃん” ,…]

CommentList の実装

var CommentList = React.createClass({ render: function() { var comments = this.props.comments.map(function(comment, index) { return <li key={index}>{comment}</li>; }); return ( <ul className="comment-list">{comments}</ul> ); }});

// comments 配列の例// [“ こんにちは” , “ プロ生ちゃん” ]

// comments 配列の例// [“ こんにちは” , “ プロ生ちゃん” ]

CommentList の実装

var CommentList = React.createClass({ render: function() { var comments = this.props.comments.map(function(comment, index) { return <li key={index}>{comment}</li>; }); return ( <ul className="comment-list">{comments}</ul> ); }});

コメントの配列からコンポーネントの配列を作る

CommentList の実装

var CommentList = React.createClass({ render: function() { var comments = this.props.comments.map(function(comment, index) { return <li key={index}>{comment}</li>; }); return ( <ul className="comment-list">{comments}</ul> ); }}); key 属性にユニークな値を設定しておくと

更新時の差分計算が効率的になる

// comments 配列の例// [“ こんにちは” , “ プロ生ちゃん” ]

CommentList の実装

var CommentList = React.createClass({ render: function() { var comments = this.props.comments.map(function(comment, index) { return <li key={index}>{comment}</li>; }); return ( <ul className="comment-list">{comments}</ul> ); }});

コンポーネントの配列を設定

// comments 配列の例// [“ こんにちは” , “ プロ生ちゃん” ]

作るコンポーネント

CommentApp コンポーネント

CommentList コンポーネント

CommentApp コンポーネント

•コメント入力して Submit したらコメントを追加し,入力欄を空にする• 入力された文字列を管理する必要がある

•書き込んだコメントの一覧を表示する• 書き込んだコメントの配列を持つ必要がある

コンポーネント内で変化する値を管理し,値が更新されたら再描画する必要がある

コンポーネント内で変化する値

•コンポーネントの内部状態という

•コンポーネント内では this.state を使って内部状態参照する

• setState を使って内部状態を更新する

CommentApp の初期内部状態の定義

var CommentApp = React.createClass({ getInitialState: function() { return { comments: [], inputValue: '' } }, …});ここで定義した値は this.state で参照できる

入力されたコメントの文字列を格納する

コメントリストに表示するコメントの配列

render 関数の実装var CommentApp = React.createClass({ … render: function() { return ( <div> <form className="comment-form" onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} /> <input type="submit" value="add" /> </form> <CommentList comments={this.state.comments} /> </div> ); }});

コメント入力欄

コメントリスト

入力欄の値の更新var CommentApp = React.createClass({ … render: function() { return ( <div> <form className="comment-form" onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} /> <input type="submit" value="add" /> </form> <CommentList comments={this.state.comments} /> </div> ); }});

コンポーネントのコメントの文字列を参照する

入力欄の値の更新var CommentApp = React.createClass({ … render: function() { return ( <div> <form className="comment-form" onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} /> <input type="submit" value="add" /> </form> <CommentList comments={this.state.comments} /> </div> ); }});

入力したら handleChange 関数を呼び出す

入力欄の値の更新 (handleChange 関数 )

var CommentApp = React.createClass({ … handleChange: function(e) { this.setState({ inputValue: e.target.value }); }, …});

this.setState 関数を実行すると,状態を更新して再描画が走る

コメントを入力から画面の更新の流れ

input の value の値が this.state.inputValue に更新される

CommentApp の render が呼び出される

handleChange で setState を使って状態を更新

コメントの入力すると onChange イベントが発火

コメント追加の実装var CommentApp = React.createClass({ … render: function() { return ( <div> <form className="comment-form" onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} /> <input type="submit" value="add" /> </form> <CommentList comments={this.state.comments} /> </div> ); }});

form の submit が発生したらhandleSubmit を呼び出す

コメント追加の実装 (handleSubmit の実装 )

var CommentApp = React.createClass({ … handleSubmit: function(e) { e.preventDefault(); var comment = this.state.inputValue; this.setState({ comments: this.state.comments.concat(comment), inputValue: '' }); }, …});

新しいコメントを追加し,入力文字列を空にして状態を更新

CommentApp の実装var CommentApp = React.createClass({ … render: function() { return ( <div> <form className="comment-form" onSubmit={this.handleSubmit}> <input type="text" value={this.state.inputValue} onChange={this.handleChange} /> <input type="submit" value="add" /> </form> <CommentList comments={this.state.comments} /> </div> ); }});

this.state.comments がを更新したらCommentList が再描画される

Submit してからの流れコメント追加まで

CommentList の render が呼び出されて再描画されコメントが追加される

CommentList に更新されたコメントの配列を渡す

CommentApp.render が呼び出される

handleSubmit で setState を使って状態を更新

コメントを入力して Add をクリック すると onSubmit イベントが着火

サンプルでの学び

•コンポーネントの組み合わせ方

•イベントハンドラの登録方法

•内部状態の持ち方と更新の仕方

React の便利な機能を少し紹介

PropTypes

• this.props の値のバリデーションができる• バリデーションに引っかかるとコンソールで警告してくれるvar UserLabel = React.createClass({ propTypes: { // userName は文字列で必須 userName: React.PropTypes.string.isRequired, // size は数値 size: React.PropTypes.number, // onClick は関数 onClick: React.PropTypes.func }, // ...});

PropTypes のエラーを見てみる

•サンプル•UserLabel コンポーネントに渡す値を変更すると開発者ツールに警告が出る• http://goo.gl/uxogKO

•参考資料• https://facebook.github.io/react/docs/reusable-components.html

さらに学ぶには?

•O’reilly 社の「入門 React – コンポーネントベースの Web フロントエンド開発」• http://www.oreilly.co.jp/books/9784873117195/

•React の公式ドキュメント• https://facebook.github.io/react/docs/getting-started.html

React を始めるときに便利なツール

Yeoman + react-gulp-browserify

•Yeoman•プロジェクトのひな形を作るツール• 0 作るのは面倒なのでこれでプロジェクトのひな形を作ると楽

• react-gulp-browserify• react アプリのためのひな形•ファイル更新時の自動ビルド•テストなども入っている

React Developer Tool

•Chrome の拡張機能•コンポーネントの構造の確認•コンポーネントの props や state の値の確認ができる•Chrome で開発者ツールを開くとコンソールにこの拡張を入れるように促される

まとめ

今回はなしたこと

•React とは•React の基本的な使い方•便利なツール

React を使ってみた感想

•最初 JSX を見て「 ??? 」になったが,書いてみるとシンプルで覚えやすい•UI パーツの書き方が統一される•オレオレ実装の UI パーツが減るかも

•警告が親切でデバッグしやすい

React を使ってみた感想

•DOM を勝手に更新してしまうのでUI周りのライブラリを使うときは気をつける必要がある•かっちりしているので、さっと作るアプリには向かない

React はいかがでしたか?

ぜひこれを期に React を勉強してみてはいかがでしょう