Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

さわってみようReact.js、AngularJS(1系、2系)

2,313 views

Published on

ビズリーチ D3 フロントエンド技術勉強会

Published in: Technology
  • Be the first to comment

さわってみようReact.js、AngularJS(1系、2系)

  1. 1. 吉本和弘 さわってみよう React.js・AngularJS(1系、2系)
  2. 2. 自己紹介 ・吉本和弘 ・株式会社ビズリーチ所属 ・サーバーサイドエンジニア ・仕事で使っている技術 Java、JavaScript(jQuery)、HTML、CSS MySQL、AWS、Linux、Android、iOS(Swift) zuknow – 友達とクイズで競える学習アプリ https://www.zuknow.net/ キャリアトレック–レコメンド型転職サイト https://www.careertrek.com/
  3. 3. React.js ・Facebookが作ったViewのライブラリ ・フレームワークでなく、UIライブラリ ・Virtual DOM DOMの状態をデータとして持ち、 状態が変化したらDOMを再生成する(差分を作成) ・コンポーネントベース ・データバイディング(props) ・状態管理(state) React.jsでVirtual DOMを定義する
  4. 4. コンポーネントベース - CommentBox - Comment var Comment = React.createClass({ <div>comment</div> }); var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <Comment /> </div> ); } }); ReactDOM.render( React.createElement(CommentBox, null), document.getElementById('content') ); コンポーネントにDOMを 定義し、コンポーネントを 組み合わせる。 コンポーネントの定義に従 い、DOMが生成される。
  5. 5. props var CommentBox = React.createClass({ render: function() { return ( <div className=”CommentBox"> <h1>Comments</h1> <Comment data={this.data} /> </div> ); } }); var Comment = React.createClass({ render: function() { return ( <div className=“Comment"> {this.props.data} </div> ); } }); CommentBox Comment ・dataの値を受け渡す ・CommentBoxでdataを更新したら、 自動的にdataの値を受け渡す
  6. 6. state var CommentBox = React.createClass({ getInitialState: function() { return {data: []}; }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data} /> <CommentForm /> </div> ); } }); ・コンポーネントの状態をもつ、ミュータブル(不変)な値 ・コンポーネント自身の状態をもつ stateに対して、 ・props はイミュータブル(可変)な値 ・propsは親の状態をもつ { data=[ “コメント1”, “コメント2”] }
  7. 7. propsとstate var CommentBox = React.createClass({ render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <Comment data={this.state.data} /> <CommentForm /> </div> ); } }); {data: “コメント1”} this.setState({data: “コメント 2”}); var Comment = React.createClass({ render: function() { return ( <div className="comment"> {this.props.data} </div> ); } }); {data: “コメント2”} <div>コメント1</div> <div>コメント2</div> state DOM
  8. 8. イベントハンドル var CommentBox= React.createClass({ onClick(e) { this.setState(・・・); }, render() { return ( <div> <span>click count is {this.state.count}</span> <button onClick={this.onClick}>click!</button> </div> ); } }); 基本的なイベントはサポートされていて、 例えばClickイベントを処理したい場合
  9. 9. イベントハンドル(子のイベント) var CommentBox= React.createClass({ comment() { this.setState(・・・); }, render() { return ( <div> <Comment comment={this.comment} data={this.state.data}/> </div> ); } }); 子のイベントを親でハンドリングする →子のイベントを親に受け渡す イベントをハンドリングし、stateを更新する →子コンポーネントのDOMが更新される var Comment= React.createClass({ render() { return ( <div> <button onClick= {this.props.comment}/> <p>{this.props.data}</p> </div> ); } });
  10. 10. サンプルプログラムの仕様 ・現在地周辺の飲食店の一覧を表示 ・一覧に表示された飲食店を お気に入りに追加できる ・お気に入りをクリアできる
  11. 11. 構築手順 (1)node.jsをインストール(brew install node) (2)git clone https://github.com/KazuhiroYoshimoto/sample_react_angular.git (3)npm install package.jsonの内容に従って、packageがインストールされる (4)http-server (5)「/public/common/common.js」の 「COMMON.config.keyid」にぐるなびAPIのKeyIdを設定
  12. 12. アクセスURL 1.React http://localhost:8080/react/ 2.Angular1 http://localhost:8080/angular1/ 3.Angular2 http://localhost:8080/angular2/
  13. 13. コンポーネント構成 -Index -SearchResultList -SearchResult -LikeButton Indexコンポーネントで、状態管理を行う ・「検索する」ボタンのクリックイベントをハンドル →API連携→state更新→DOMが更新される ・「お気に入りに追加」ボタンのクリックイベント をハンドル→state更新→DOMが更新される
  14. 14. Indexコンポーネント ・state ・イベントハンドラ ・レンダリング onLike: function() ・・ this.setState({shops: shops}); <div className="index"> <p> <a href="javascript:void(0);" onClick={this.onSearch}>検索する</a> </p> <SearchResultList data={this.state.shops} onLike={this.onLike} /> </div> onSearch: function() ・・ this.setState({shops: shops}); shops: [];
  15. 15. SearchResultListコンポーネント ・イベントハンドラ(onLike) 親から子に受け渡す ・レンダリング 親(Indexコンポーネント)のdataを取得し、 リストをJSのmap関数で出力 リストを出力するときは、key属性が必要 var data = this.props.data; var result = function(row,i){ return ( <SearchResult key={i} data={row} onLike={this.props.onLike}/> ); }; return ( <ul>{this.props.data.map(result,this)}</ul> );
  16. 16. SearchResultコンポーネント ・イベントハンドラ(onLike) propsで渡されたidを取得 親(SearchResultListコンポーネント)のonLike関数を呼び出す ・レンダリング var id = this.props.data.id; this.props.onLike(id); var shop = this.props.data; <li className="search-result"> <div> <p> {shop.name} </p> {imageArea} <p>住所: {shop.address}</p> <LikeButton isLiked={shop.isLiked} id ={shop.id} onLike={this.onLike}/> </div> </li>
  17. 17. LikeButtonコンポーネント ・イベントハンドラ クリックイベントで、 親(SearchResultListコンポーネント)のonLike関数を呼び出す ・レンダリング var isLiked = this.props.isLiked; if(isLiked){ return( <p>お気に入りに追加済み</p> ); }else{ return( <p><a href="javascript:void(0);" onClick={this.props.onLike}> お気に入りに追加する</a></p> ); }
  18. 18. AngularJS(1系) ・Google製のMVW(Model-View-Whatever)フレームワーク (MVCの派生パターン) ・モデル(データ)とビュー(表示)によるデータバイディング ・ディレクテイブ、サービス module.controller('AppController', function($scope, $http) { //イベントハンドラ $scope.search = function() { ・・・ $scope. searchShops=[・・・] }; //モデル $scope. searchShops = [ {name:”お店1”,address:”住所1”}, {name:”お店2”,address:”住所2”} ] };
  19. 19. AngularJS(1系) データ(app.js) 画面(index.html) <ul> <li ng-repeat="shop in searchShops”> {{ shop.name }} {{ shop.address }} </li> </ul> $scope. searchShops
  20. 20. AngularJS(1系)のメリット・デメリット ・大規模、複雑になったときに状態を管理するのが難しい ・ルールからはずれたことをする場合に、 柔軟に対応するのが大変 メリット 設計や実装のルールがある程度強制され、 それに従うことで、コード量や品質の差を少なくし、 生産性向上が期待できる (管理画面などのCRUD系に有効) デメリット
  21. 21. AngularJS(2系) ・1系とは別物 ・コンポーネント指向、Virtual DOM ・パフォーマンス向上 ・ControllerやScopeは廃止 ・ディレクテイブ (1系) <p ng-if=“??”>・・・</p> (2系) <p *ngIf=“??”>・・・</p>
  22. 22. AngularJS(2系) var Index = ng .Component({ selector: ‘index’, //紐づけるセレクタを指定 directives: [ng.CORE_DIRECTIVES], //利用するディレクテイブを指定 //htmlを記述 template: [ ・・・ ].join('') }) .Class({ onClick: function(id){ ・・・ } }); document.addEventListener('DOMContentLoaded', function () { ng.bootstrap(Index); }); app.js index.html <index></index>

×