SIROK技術勉強会 #1 「Reactってなんだ?」

Preview:

Citation preview

Reactってなんだ?

JavaScriptで UIを作るためのライブラリ

SIROKのUI構築の変遷

My365: PHP テンプレートエンジンとして使う

ピプル Apache Velocity サーバサイド処理

Growth Push Backbone + Handlebars

本格的にJSでUI実装

Growth Point TypeScript + Backbone +

Handlebars 生のJSつらくなってきた

Growthbeat TypeScript + Backbone + Underscore template ロジックレスつらい

新規プロジェクト TypeScript + React?

Reactとは?

JavaScriptで UIを作るためのライブラリ

MVCのViewの部分のみを担当 基本的にそれ以外には関わらない

高速な描画処理 Virtual DOMという概念

ビュー操作の難しさ

DOM操作は遅い。 想像しているよりもずっと。

大抵は、こういうことがしたい。

データ (JS Object)

ビュー (HTML)

サーバから取得したり、ユーザーが変更してデータが変化。

データ (JS Object)

ビュー (HTML)

更新

データの更新に合わせてビューも更新する必要がある。

データ (JS Object)

ビュー (HTML)

更新

1. まるごと書き換えるパターン 2. 差分更新するパターン

まるごと書き換えるパターン データが少しでも変化したら、

HTMLを全部まるごと書き換える。

データ (JS Object)

ビュー (HTML)

テンプレートで全更新

DOM操作は遅い。 想像しているよりもずっと。

リストオブジェクトのデータ追加 <table>への大量の行追加

突然の死

エンジニアががんばって DOMを差分更新するパターン

データ (JS Object)

ビュー (HTML)

変化したところだけ 差分更新

どこかでミスして 変な中間状態におちいる

結局のところ死

1. 簡単だけど遅い 2. 高速だけど複雑

なぜReactか?

結局のところ死

そこでVirtual DOM

データ (JS Object)

ビュー (HTML)

テンプレートで全更新 (簡単)

Virtual DOM

システム的に差分更新 (高速)

エンジニア的には、常に全更新で良いので簡単で間違えない。

システム的には、差分更新なので高速に実行可能。

つまり、簡単で速い

1. Virtual DOMの全更新 2. Virtual DOMの差分計算 3. DOMへの差分適用

・・・は「DOMの全更新」より速い

Hello React

<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <script src="build/JSXTransformer.js"></script> </head> <body> <div id="example"></div> <script type="text/jsx"> React.render( <h1>Hello, world!</h1>, document.getElementById('example') ); </script> </body> </html>

React.render( <h1>Hello, world!</h1>, document.getElementById('example') );

#example要素の中に <h1>Hello, world!</h1>

を表示

React.render( <h1>Hello, world!</h1>, document.getElementById('example') );

JSX

これじゃない

これでもない

JSX is a JavaScript syntax extension that looks similar to XML.

XMLっぽいのが使えるJavaScript

<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <script src="build/JSXTransformer.js"></script> </head> <body> <div id="example"></div> <script type="text/jsx"> React.render( <h1>Hello, world!</h1>, document.getElementById('example') ); </script> </body> </html>

JSXTransformerで JavaScriptに変換してから実行

JSX JavaScript

react.js

JSXTransformer

実行

JSXのプリコンパイル

実行時にコンパイルしたくない。

npm install -g react-tools

JSX JavaScript

react.js

react-tools

実行

React.render( React.createElement("h1", null, "Hello, world!"), document.getElementById('example') );

<!DOCTYPE html> <html> <head> <script src="build/react.js"></script> <!--<script src="build/JSXTransformer.js"></script>--> </head> <body> <div id="example"></div> <script src="build/helloworld.js"></script> </body> </html>

Component

Componentとは?

Viewをオブジェクト化したもの

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

React#createClassで、Componetを作成

renderメソッドで、 描画するDOM定義を返す。

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

Componentに対して、 propsで値の受け渡しが可能

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

props

props?

Componentに対して 外部から値を渡す受け口

propsが外部との インタフェースになる

propsで何でも渡せる(関数も)

propsはImmutableに扱う 外からpropsを渡し直すときは、 setProps、replaceProps

state

state?

Component内部の 状態を保持するための変数

propsが外部とのインタフェース stateは内部の状態変数

State

props render

Component

var Hello = React.createClass({ getInitialState() { return { name: 'World' }; }, onClick() { this.setState({ name: this.state.name + '!' }); }, render() { return ( <div> <h1>Hello {this.state.name}</h1> <button onClick={this.onClick}>click</button> </div> ) } });

あるComponentのstateが、 その子のpropsになるかも

Users

User ID

Name …

User ID

Name …

[ {ID, Name, …}, {ID, Name, …}, {ID, Name, …}, … ]

var User = React.createClass({ render() { return ( <li>Hello {this.props.user.name}</li> ) } });

var Users = React.createClass({ // …(略)… render() { var users = this.state.users.map((user) => { return <User user={user}/> }); return ( <ul> {users} </ul> ) } });

まとめ

便利そう。

次回予告

・週に1回、誰かが発表しています。 ・発表者はリレー形式でやってい

ます。 ・内容は指名された人が主張したいことや興味があることなど ・時間は、10~30分程度です。 ・形式も色々です。(プレゼン形式、

クイズ形式、など) ・途中参加、途中退出もOKです。 ・飛び込みでの発表もOKです。

@uchidas

3/10(火) 19:00~