Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
既存プロダクトのViewをReactに置き換える
Search
boiyama
December 15, 2016
Programming
2.3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
既存プロダクトのViewをReactに置き換える
【ヒカ☆ラボ】最新フロントエンドフレームワークを利用した開発事例!
https://atnd.org/events/83403
用の資料です
boiyama
December 15, 2016
More Decks by boiyama
See All by boiyama
Reproのビジネスサイドを支えるJS
boiyama
0
200
バックオフィスに行ったソフトウェアエンジニアの業務効率化事例
boiyama
1
300
2018年、IE6対応サイトを作る
boiyama
4
1k
ヤバいESLint/TSLintルール作っちゃったかもしれない
boiyama
0
1.5k
チームをCQRS
boiyama
1
1.7k
フロントエンドのサーバーレス SSR編
boiyama
0
730
Serverless for Front-end Server-Side Rendering
boiyama
1
150
Learning Elm in JS
boiyama
1
580
JSでElmを学ぶ
boiyama
0
120
Other Decks in Programming
See All in Programming
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
190
sbt 2.0: takeoff
eed3si9n
0
160
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
140
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
190
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
3
650
Lambda durable functionsでHuman in the Loopを楽に…楽に……
har1101
0
150
ジョジョの世界をXRで再現する
mofurune
0
180
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
360
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
160
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
440
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
340
Featured
See All Featured
WCS-LA-2024
lcolladotor
0
900
Music & Morning Musume
bryan
48
7.4k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
480
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
290
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Un-Boring Meetings
codingconduct
0
460
The Cost Of JavaScript in 2023
addyosmani
55
10k
What's in a price? How to price your products and services
michaelherold
247
13k
Exploring anti-patterns in Rails
aemeredith
4
540
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
67k
Designing for humans not robots
tammielis
254
26k
Faster Mobile Websites
deanohume
310
32k
Transcript
طଘϓϩμΫτͷViewΛ Reactʹஔ͖͑Δ Dec 15 2016 @boiyaa
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ϓϩϑΟʔϧ ▸ @boiyaa ▸ 33ࡀ ▸ ϑϧεέοϕΤϯδχΞ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ͢͜ͱɾ͞ͳ͍͜ͱ ▸ ͢͜ͱ ▸ طଘϓϩμΫτʹReactΛಋೖ͢Δ͜ͱʹͨ͠എܠ ▸ ࣮αϯϓϧ ▸ https://github.com/boiyaa/todomvc-backbone-react
▸ ͞ͳ͍͜ͱ ▸ πʔϧͱ͔ES6ͱ͔ͷৄ͍͠༰
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ࣮ݱࡏ ▸ View͚ͩஔ͖͑ΔͷΊ͍ͯ·͢ʢٕज़తෛ࠴తͳཧ ༝Ͱʣ ▸ ͜ͷεϥΠυͰɺViewΛReactʹஔ͖͑Α͏ͱࢼߦࡨޡ ͍ͯͨ࣌͠ͷ͓Λ͠·͢
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ৽ٕज़Λݕ౼ͨ͠എܠ ▸ 4લʹ࡞ΒΕͨۀγεςϜ ▸ ϑϩϯτΤϯυFWʹBackbone.jsΛ࠾༻ ▸ ػೳͷܧ͗͠Λ܁Γฦ͍ͯͬͨ݁͠ՌɺDOMૢ࡞ͷॲཧ͕ᷓΕ͔͑ͬͨ Backbone ViewʹͳΔ
▸ ͏গ͠εϚʔτʹUIΛ࡞ΕΔํ๏ʹม͑ΔͨΊɺjQueryʹґଘ͠ͳ͍React ͱAngular2͕ީิʹ্͕Δ ▸ Ͱ͖Εطଘࢿ࢈׆༻͍ͨ͠ͱ͍͏͜ͱͰɺUI·ΘΓͷΈΛReactʹஔ͖ ͑ΔํࣜͱɺAngular2Ͱ1͔Β࡞Γ͢ํࣜͷ̎௨Γݕ౼͢Δ͜ͱʹͳͬͨ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ࣌ͷݕূ༰ ▸ ̍൪ӈͷ߲͍͍ͬͨͳΜͩͱ͍͏ײ͡Ͱ͕͢ɺݱߦʹͦ͏͍͏ը໘͕͋Γɺ ສݸͷDOMͷඳըૢ࡞ʹ͕͔͔࣌ؒΔΑ͏ͩͱଞ߲͕ັྗతͰ࠾༻Ͱ ͖ͳ͍ͱ͍͏͜ͱͰ༻ҙ͞Ε߲ͨͰ͢ɻʢWhy?ʣ ▸ ݁ՌɺAngular2མબ͠ɺBackboneͷΈͷը໘ͱBackbone + Reactͷը໘Λ
͍͚͍ͯ͘ͱ͍͏͜ͱʹͳΓ·ͨ͠ ֶशίετ ੜ࢈ੑ อकੑ طଘࢿ࢈׆༻ ̍ສߦදૢ࡞ ύϑΥʔϚϯε Backbone ˕ ̋ ˚ ˕ ̋ Backbone + React ̋ ˕ ̋ ̋ ˚ Angular2 ˚ ˕ ̋ × ˚
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Reactʹ͍ͭͯ ▸ MV*Ͱ͍͏ViewͷΈఏڙ͢ΔϑϨʔϜϫʔΫ ▸ React͚ͩͳΒ֮͑Δ͜ͱগͳ͍Ͱ͢ ▸ React ComponentΫϥεΛܧঝ͠ɺHTML, CSS,
JSͷͻͱ͔ͨ·ΓΛఆٛͨ͠ίϯ ϙʔωϯτΛ࡞Δͷ͕جຊతͳ͍ํͰ͢ɻ ▸ ίϯϙʔωϯτɺJSXͱ͍͏จ๏ΛͬͯHTMLͷΑ͏ʹݺͼग़͠·͢ʢྫɿ <Example hoge=“fuga” />ʣ ▸ ίϯϙʔωϯτʹͨ͠propsɺίϯϙʔωϯτ͕࣋ͭstateʹೖΓɺͦΕ Βͷ͕ߋ৽͞ΕΔͱίϯϙʔωϯτ͕࠶ඳը͞Ε·͢ ▸ Πϕϯτॲཧλάଐੑʹઃఆ͠·͢ʢྫɿ<Example onClick={handleClick} />ʣ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Backboneʹ͍ͭͯ ▸ RESTful APIͱͷ࿈ܞΛγϯϓϧʹநԽɻେ͖̏ͭ͘ͷػೳΛ࣋ͪ·͢ ▸ Model: APIͷ୯Ϧιʔεͱಉظ ▸ Collection:
Modelͷू߹ͰɺAPIͷෳϦιʔεͱಉظ ▸ View: ඥͮ͘ModelCollectionͷσʔλΛDOMʹө͠ɺDOMͷϢʔβೖྗ ΛModelCollectionʹө
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ReactԽ Part.1 : ΊͪΌΊͪΌബ͘ReactΛ͏ ▸ Ұ൪؆୯ͳ͍ํͰ͢ɻ ؆୯ʹಋೖͰ͖·͕͢ɺ͜ͷ͍ํͰReact͍͍ͨਓ͍ͳ͍ͱ ࢥ͏ͷͰɺࢀߟఔʹհ͠·͢ ▸
ࢀߟURL ▸ https://facebook.github.io/react/docs/installation.html#using-a-cdn ▸ https://facebook.github.io/react/docs/react-without-es6.html ▸ https://facebook.github.io/react/docs/react-without-jsx.html ▸ ຊདྷReactɺYarn,npmͷύοέʔδϚωʔδϟɺwebpack,Browserifyͷόϯυϥɺ BabelͷίϯύΠϥΛซͤͯ׆༻͢Δ͜ͱΛਪ͍ͯ͠·͕͢ɺࠓճͦΕΒͷπʔϧ ΛΘͣ͏ํ๏Ͱ͢
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Α͋͘ΔBackboneϓϩδΣΫτͷྫ ▸ htmlʹςϯϓϨʔτΛॻ͍ͯɺ <script type="text/template" id="item-template"> <div class="view"> <input
class="toggle" type="checkbox" <%= completed ? 'checked' : '' %>> <label><%- title %></label> <button class="destroy"></button> </div> <input class="edit" value="<%- title %>"> </script>
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Α͋͘ΔBackboneϓϩδΣΫτͷྫ ▸ BackboneViewͰɺUnderscoreͱjQueryͰඳը͠·͢Ͷ template: _.template($('#item-template').html()), render: function () {
this.$el.html(this.template(this.model.toJSON())); },
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ htmlʹCDNͷReactΛه͠ɺ <script src="https://unpkg.com/react@15/dist/react.js"></ script> <script src="https://unpkg.com/react-dom@15/dist/react- dom.js"></script>
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ htmlͷςϯϓϨʔτΛফͯ͠ɺReact ComponentΛ࡞Γ·͢ var Item = React.createClass({ render:
function() { return React.createElement('div', null, React.createElement('div', {className: 'view'}, React.createElement('input', { className: ‘toggle', type: ‘checkbox', checked: this.props.completed }, null), React.createElement('label', null, this.props.title), React.createElement('button', {className: 'destroy'}, null) ), React.createElement('input', { className: ‘edit', defaultValue: this.props.title }, null) ); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ BackboneViewͷඳը͢Δͱ͜ΖΛॻ͖͑·͢ render: function () { ReactDOM.render( React.createElement(Item,
this.model.toJSON(), null), this.$el.get(0) ); },
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ <script type="text/template" id="item-template"> <div class="view"> <input class="toggle" type="checkbox" <%=
completed ? 'checked' : '' %>> <label><%- title %></label> <button class="destroy"></button> </div> <input class="edit" value="<%- title %>"> </script> var Item = React.createClass({ render: function() { return React.createElement('div', null, React.createElement('div', {className: 'view'}, React.createElement('input', { className: ‘toggle', type: ‘checkbox', checked: this.props.completed }, null), React.createElement('label', null, this.props.title), React.createElement('button', {className: 'destroy'}, null) ), React.createElement('input', { className: ‘edit', defaultValue: this.props.title }, null) ); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ template: _.template($('#item-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); }, render:
function () { ReactDOM.render( React.createElement(Item, this.model.toJSON(), null), this.$el.get(0) ); },
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part.1 ·ͱΊ ▸ ͱͯݟͮΒͯ͘ݏͰ͢Ͷɻ ▸ ReactͬΆ͞ΛࣺͯΕɺಋೖࣗମ؆୯ʹͰ͖Δͱ͍͏ྫ Ͱͨ͠
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ReactԽ Part.2 : JSXͰBackbone TemplateΛஔ͖͑Δ ▸ ύοέʔδϚωʔδϟɺόϯυϥɺίϯύΠϥΛಋೖ͢Δ͜ͱʹͳΓ·͕͢ɺ ReactࣗମͰ֮ ͑Δ͜ͱগͳ͍͍ํͰ͢ɻ
πʔϧʹ׳Ε͍ͯͳ͚Εɺ࿅शʹͪΐ͏Ͳ͍͍͘Β͍ͷม ߋྔͰ͠ΐ͏ɻ ▸ ࢀߟURL ▸ https://nodejs.org/en/download/package-manager/ ▸ https://yarnpkg.com/en/docs/install#alternatives-tab ▸ https://facebook.github.io/react/docs/installation.html#installing-react ▸ https://webpack.js.org/guides/installation/ ▸ https://babeljs.io/docs/setup/#installation ▸ https://facebook.github.io/react/docs/introducing-jsx.html
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ඞཁͳͷΛΠϯετʔϧ͢Δ ▸ ύοέʔδϚωʔδϟYarnΛΠϯετʔϧ ▸ ύοέʔδϚωʔδϟͱ͍͑npmͰ͕͢ɺReactؔ࿈ͷυΩϡϝϯτͰyarnϕʔ εͰॻ͔Ε͍ͯΔ͜ͱ͕ଟ͍ͷͰࠓճͪ͜ΒΛ͍·͢ɻ ▸ ίϚϯυେମޓ͍ͯ͠ΔͷͰɺnpm͕͍͍ํదٓஔ͖͑ͯಡΜͰ͍ͩ͘͞ɻ ▸
npmίϚϯυରরදɿ https://yarnpkg.com/en/docs/migrating-from-npm ▸ YarnΛͬͯɺReactͱɺόϯυϥʹwebpackɺίϯύΠϥʹbabelΛΠϯετʔϧ yarn add react react-dom yarn add webpack babel-core babel-loader babel-preset-react --dev
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ React ComponentΛ࡞ͬͯΈ·͢ ▸ ҰݟHTMLʹݟ͑Δ͜ͷจ๏͕JSXͰ͢ɻ className, defaultValueগ͠HTMLͱ ҧ͏ଐੑ͕͋Γ·͢Ͷɻ
var Item = React.createClass({ render: function() { return ( <div> <div className="view"> <input className="toggle" type="checkbox" checked={this.props.checked} /> <label>{this.props.title}</label> <button className="destroy"></button> </div> <input className="edit" defaultValue={this.props.title} /> </div> ); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ BackboneViewͷඳը͢Δͱ͜ΖΛॻ͖͑ͯΈ·͢ render: function () { ReactDOM.render( <Item
title={this.model.get('title')} checked={this.model.get('completed')} />, this.$el.get(0) ); },
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ <script type="text/template" id="item-template"> <div class="view"> <input class="toggle" type="checkbox" <%=
completed ? 'checked' : '' %>> <label><%- title %></label> <button class="destroy"></button> </div> <input class="edit" value="<%- title %>"> </script> var Item = React.createClass({ render: function() { return ( <div> <div className="view"> <input className="toggle" type="checkbox" checked={this.props.checked} /> <label>{this.props.title}</label> <button className="destroy"></button> </div> <input className="edit" defaultValue={this.props.title} /> </div> ); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ template: _.template($('#item-template').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); }, render:
function () { ReactDOM.render( <Item title={this.model.get('title')} checked={this.model.get('completed')} />, this.$el.get(0) ); },
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ ςϯϓϨʔτ෦ࣅͨΑ͏ʹهड़Ͱ͖ΔΑ͏ʹͳΓɺඳ ը෦͕ײతͳදݱʹͳΓ·ͨ͠Ͷ ▸ ͨͩ͠ɺ͔͜͜ΒϏϧυ͢Δ࡞ۀ͕ඞཁͰ͢
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ webpack.config.jsΛ࡞ΓɺϏϧυઃఆΛॻ͖·͢ module.exports = { entry: { 'components/Item.js':
'./js/components/Item.js', 'views/todo-view.js': './js/views/todo-view.js' }, output: { path: `${__dirname}/dist`, filename: '[name]' }, module: { loaders: [ { test: /\.js$/, loader: 'babel', query: { presets: ['react'] }
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ package.jsonʹϏϧυεΫϦϓτΛه͠·͢ "scripts": { "build": "webpack" },
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ Ϗϧυ͠·͠ΐ͏ ▸ ͜ΕͰdistʹϏϧυͨ͠jsϑΝΠϧ͕ੜ͞ΕΔͷͰɺ͜ΕΛhtmlʹಡΈ ࠐ·ͤ·͢ yarn run build
<script src="node_modules/react/dist/react.js"></script> <script src="node_modules/react-dom/dist/react-dom.js"></ script> <script src="dist/components/Item.js"></script> <script src="dist/views/todo-view.js"></script>
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ςϯϓϨʔτΛReactԽ͢Δ ▸ ϑΝΠϧ͕Ͱ͖ΔͨΊɺϖʔδؒͰͷςϯϓϨʔτͷڞ༗͕༰қʹ ▸ ͨͩɺςϯϓϨʔτϑΝΠϧΓग़͚ͩ͠Ͱ͋ΕɺUnderscore TemplateͰJSTίϯύΠϥΛ࣮͑ݱͰ͖·͢ɻ ▸ ͦΕ͚ͩͩͱ͍ͨͨ͠ϝϦοτʹͳΓ·ͤΜͶ ▸
JSXͷ͞Βʹ͍͍ͱ͜ΖɺJSXͰReact ComponentΛݺͼग़͢͜ͱ ͕Ͱ͖ΔͷͰɺΑΓݟ͘͢ίϯϙʔωϯτͷೖΕࢠΛදݱͰ͖Δͱ ͜ΖͰ͢
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Underscore Templateͷ߹ ▸ ཁૉʹࢠཁૉΛՃ͢ΔͳΒɺView͔ΒViewΛݺͼग़ͯ͠ɺ DOMʹૠೖ͢ΔॲཧΛॻ͘͜ͱʹͳΓ·͢ ▸ html <script type="text/template"
id="parent"> <div class="parent"></div> </script> <script type="text/template" id="child"> <div class="child"><%- text %></div> </script>
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Underscore Templateͷ߹ ▸ js var ChildView = Backbone.View.extend({ template:
_.template($('#child').html()), render: function () { this.$el.html(this.template(this.model.toJSON())); } }); var ParentView = Backbone.View.extend({ template: _.template($('#parent').html()), render: function () { this.$el.html(this.template()); var parent = this.$el.find('.parent'); this.collection.each(function (model) { var child = new ChildView({model: model}); parent.append(child.$el); }); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Reactͷ߹ ▸ ίϯϙʔωϯτ͔ΒίϯϙʔωϯτΛݺͼग़ͤ·͢ var Parent = React.createClass({ render: function()
{ var children = []; this.props.collection.each(function (model) { children.push(<Child model={model}>); }); return <div className="parent">{children}</div>; } }); var Child = React.createClass({ render: function() { return <div className="child">{this.props.text}</div>; } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Reactͷ߹ ▸ ͳͷͰView1ͭʹͳΓ·͢ var ParentView = Backbone.View.extend({ render: function
() { ReactDOM.render( <Item collection={this.collection} />, this.$el.get(0) ); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part.2 ·ͱΊ ▸ ͜ͷΑ͏ʹγϯϓϧʹهड़Ͱ͖ɺؾܰʹڞ௨UI෦Λͯ͠͠·͑·͢ɻ Child͕ඳըͷΈͰ͍͍߹ɺ͜ͷख๏ͰऔΓೖΕΔͷ͋Γͩͱࢥ͍·͢ɻ ▸ ͔͠͠ͳ͕Βɺ Childʹੜ࣌Ϣʔβೖྗ࣌ͷΠϕϯτॲཧΛ࣋ͨͤͯɺͦΕڞ௨Խ͍ͨ͠ ͱ͍͏߹ɺ
React ComponentͰͦ͏͍ͬͨࣄॻ͚·͕͢ɺͷʹΑͬͯBackbone View ʹॻ͍ͯ͋ͬͨΓReact Componentʹॻ͍ͯ͋ͬͨΓ͢ΔͱɺՄಡੑอकੑ ΛԼ͛ͯ͠·͏ͷͰɺ ݁ہChildͷBackbone ViewΛ࡞ͬͯParentView͔Βݺͼग़͢͜ͱʹͳΓ·͢ɻ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ReactԽ Part.3 : Backbone ViewΛReact Componentʹஔ͖͑Δ ▸ React ComponentͷػೳͰBackbone
ViewͰ͍ͬͯΔ͜ͱΛҠ২͠·͢ɻ ▸ มߋྔ݁ߏ͋ΓɺES2015+Λಋೖ͠JSͷॻ͖ํ͕݁ߏมΘΓ·͕͢ɺ Backboneʹͳ͍ViewͷՄಡੑɾอकੑ্ͷͨΊͷ༷ʑͳϝϦοτΛڗ डͰ͖·͢ɻ ▸ ࢀߟURL ▸ https://facebook.github.io/react/docs/components-and-props.html ▸ https://facebook.github.io/react/docs/handling-events.html
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Α͋͘ΔBackbone View var View = Backbone.View.extend({ tagName: 'li', //
ユーザ入力イベントとハンドラの紐付け events: { 'click .toggle': 'toggleCompleted' }, // モデル変更イベントとハンドラの紐付け initialize: function () { this.listenTo(this.model, 'change', this.render); }, render: function () { this.$el.html(this.template(this.model.toJSON())); }, toggleCompleted: function () { this.model.toggle(); } });
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ React ComponentԽ // 依存ライブラリの参照はHTMLではなくjsに書く import Item, {Component} from 'react';
// classが使える class Todo extends Component { // 描画後イベント componentDidMount() { // モデル変更イベントとハンドラの紐付け this.props.model.on('change', this.handleChangeModel); } handleChangeModel() { // 描画実行 this.forceUpdate(); } handleClickToggle() { this.props.model.toggle(); } 〜つづく〜
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ React ComponentԽ 〜つづき〜 render() { const title = this.props.model.get('title');
const completed = this.props.model.get('completed'); // ユーザ入力イベントとハンドラの紐付け return ( <li> <div className="view"> <input className="toggle" type="checkbox" checked={completed} onClick={this.handleClickToggle} /> <label>{title}</label> </div> </li> ); } }
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ React ComponentԽ ▸ BackboneɺϚʔΫΞοϓͱJSΛ͠·͕͢ɺReactɺ݁߹͠·͢ɻ HTMLίʔσΟϯά͔͠Ͱ͖ͳ͍ਓͱɺϓϩάϥϚͷۀͰ͍ͬͯΔνʔϜͩͱෆ͖ʁ ▸ খ͘͞࡞ΒΕͨίϯϙʔωϯτɺ ΠϕϯτͷྲྀΕ͕ಡΈ͘͢ɺίʔυ͕ࢄ͍ͯ͠ͳ͍ͷͰɺ ࠶ར༻࣌ʹؾʹ͔͚Δ෦ݮΓ·͢ɻ
▸ ·ͨ෦Ͱఆٛ͞ΕͨϝιουCSSΫϥεӅṭ͞Εɺ ֎͔Βࢀর͢Δ͜ͱ͕Ͱ͖ͳ͍ͷͰɺ໊લͷڝ߹ͰࠔΔ͜ͱ͕ͳ͘ͳΔɺ ϝϦοτ͕͋Γ·͢ɻ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ React ComponentԽ ▸ htmlʹࢀরΛه͢Δࡍɺ webpackʹΑͬͯɺimportઌͷϑΝΠϧΛશͯΤϯτϦʔϑΝ Πϧʹ݁߹͞Ε͍ͯΔͷͰɺಡΈࠐΉͷ1ͭͰΑ͘ͳΓ·͢ <script src="dist/views/app-view.js"></script>
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part.3 ·ͱΊ ▸ Backbone ViewͰΓʹ͍͘ίϯϙʔωϯτࢦΛ༰қ ʹͰ͖·ͨ͠ ▸ UIͷΈίϯϙʔωϯτͷೖΕࢠ͚ͩͰͳ͘ɺ ςϯϓϨʔτ͚ͩͷReactԽͷ՝ͱͳΔɺػೳͷ͋Δίϯ
ϙʔωϯτͷڞ༗ɺ Backbone View͝ͱReact Componentʹஔ͖͑Δ͜ͱͰ ࣮ݱͰ͖·ͨ͠
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ReactԽ Part.4 : ComponentΛׂͰׂ͠ɺ࠶ར༻ੑΛߴΊΔ ▸ Part3ͰɺϩδοΫͷ͋ΔComponent෦Ͱঢ়ଶૢ࡞Λߦ͍ͬͯΔ ͨΊɺ ෦༻ͷঢ়ଶϓϩύςΟstateΛ༻͍ͯ͠·͢ɻ ▸
͔͠͠ͳ͕ΒɺComponentεςʔτϨεʹ࡞ΒΕ͍ͯΔํ͕ɺ Մಡੑɾ࠶ར༻ੑɾςελϏϦςΟ্͕͠·͢
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Componentͷׂ ▸ ReactΛ༻͢ΔFWͷFlux UtilsReduxͰɺ ComponentΛ2ׂͭͰׂ͢Δ͜ͱΛਪ͍ͯ͠·͢ɻ ▸ 1ͭɺ͞ΕΔpropsʹԠͯ͡UIΛඳը͢ΔεςʔτϨείϯϙʔωϯτ ͏1ͭɺσʔλͱViewΛૢ࡞͢Δίϯϙʔωϯτ
લऀViews·ͨPresentational Componentsɺ ޙऀContainers·ͨContainer ComponentsͱݺΕ·͢ ▸ ࢀߟURL ▸ https://facebook.github.io/flux/docs/flux-utils.html#best-practices ▸ http://redux.js.org/docs/basics/UsageWithReact.html#presentational-and- container-components
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part3ͷComponentΛViewͱContainerʹׂ͢Δ ▸ View ▸ propsΛඳը͢Δ͚ͩ ͳͷͰFunctional Componentʹ͠·͢ ▸ https://
facebook.github.io/ react/docs/ components-and- props.html#functional- and-class-components const Item = (props) => { // 状態は外から渡される const {title, checkedToggle} = props; const handleClickToggle = () => { // 外から渡されたハンドラにそのまま返す props.onClickToggle(); } return ( <li> <div className="view"> <input className="toggle" type="checkbox" checked={checkedToggle} onClick={handleClickToggle} /> <label>{title}</label> </div> </li> ); }
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part3ͷComponentΛViewͱContainerʹׂ͢Δ ▸ Container class ItemContainer extends Component { componentDidMount()
{ this.props.model.on('change', this.handleChangeModel); } handleChangeModel() { this.forceUpdate(); } handleClickToggle() { this.state.model.toggle(); } render() { const title = this.props.model.get('title'); const completed = this.props.model.get('completed'); // Itemの状態はこちらで管理する return ( <Item title={title} checkedToggle={completed} onClickToggle={handleClickToggle} /> ); } }
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part.4 ·ͱΊ ▸ σʔλͷΓͱΓͱɺUIͷදݱ͕ผΕͨ͜ͱͰɺ ͞ΒʹUIͷ࠶ར༻ੑ্͕ͨ͠ͱࢥ͍·͢ɻ ▸ ྫ͑ɺDate PickerͷΑ͏ͳϢʔβೖྗUIɺ ೖྗʹΑͬͯͲ͏ॲཧ͢Δ͔ɺ͏ॴͰܾΊ͍ͨͷͳͷ
Ͱɺ͜ͷϓϥΫςΟε͕༗ޮʹಇ͖·͢ɻ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ReactԽ Part.5 : σʔλϑϩʔʹFluxΛऔΓೖΕΔ ▸ FluxFacebook͕ఏএ͢Δ୯ํσʔλϑϩʔΞʔΩςΫνϟ ▸ Model-ViewͰModel͕σʔλͱσʔλʹର͢ΔཁٻΛ͍࣋ͬͯ·͕͢ɺ FluxͰɺσʔλ(Store)ͱσʔλʹର͢Δཁٻ(Action)Λ͠·͢
▸ Reactɺ͜ͷΈͷதͰViewʹΘΕΔ͜ͱΛਪ͍ͯ͠·͢
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ BackboneʹFluxͷ֓೦ΛऔΓೖΕΔʹ ▸ ͷൣғΛ୲͍ͬͯΔCollectionModelΛׂ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part.5 ·ͱΊ ▸ ݱঢ়ViewModelʹϩδοΫ͕ࢄΒ͔͍ͬͯΔ͕ɺ ActionΛऔΓೖΕͨ͜ͱͰɺߋ৽ͱऔಘΛ͢Δ͜ͱ͕Ͱ͖ɺ ϩδοΫͷཧͱංେԽΛ͑ΒΕͦ͏Ͱͨ͠ ▸ ͔͠͠ɺDispatcherͱ͔ɺViewͱModelΛDispatcherͰඥ͚Δ ෦ͱ͔ɺಠ࣮ࣗ͢Δͱ͜Ζ͕৭ʑ͋ͬͯɺ݁ہBackbone
Ϣʔβʹͱֶͬͯशίετ͕͔͔ͬͯ͠·͏ײ͡Ͱ͢ ▸ ͰɺFLUXɺCQRS + Event Sourcingύλʔϯͱ͍ͬͨҰํ ͷσʔλϑϩʔτϨϯυͳͷͰੋඇ͓͓͖͍͑ͯͨ͞Ͱ͢Ͷɻ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ࣮͜ͷࠒʹ ▸ ͳΜ͔ٕज़తෛ࠴ଟա͗ͯɺReactʹஔ͖͑ʹ͍͘ॴ͕ ͋Γ͗͢Δͱ͍͏ݱ࣮ʹ໘͍ͯ͠·ͨ͠ɻ ▸ ݁ہϓϩδΣΫτෛ࠴ฦࡁͱ৽ن։ൃʹ͠·ͨ͠ɻ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ ReactԽ Part.6 : BackboneΊΔ ▸ ৽ن։ൃϓϩδΣΫτ͕࢝·ΓɺτϨϯυͷReduxͱɺ Facebook͕ϝϯςφϯε͢ΔFlux UtilsͰൺֱ͢Δ͜ͱʹͳΓ ·ͨ͠ɻ
▸ ͜ͷ2ͭͷେ͖ͳҧ͍ɺReduxʹ1ͭͷΦϒδΣΫτʹΞϓ ϦέʔγϣϯશମͷεςʔτΛ·ͱΊΔݪଇ͕͋Δɺͱ͍͏ͱ ͜ΖͰ͢ɻ ▸ ElmͷӨڹΛड͚ͨReduxɺؔܕϓϩάϥϛϯάͷ׆༻ʹ Αͬͯอकੑͷߴ͍ίʔυΛॻ͚ΔͷͰ͍͍ͱࢥ͍·ͨ͠ɻ
طଘϓϩμΫτͷViewΛReactʹஔ͖͑Δ Part.6 ·ͱΊ ▸ ͔ͳΓࡉ͔͍ίʔσΟϯάνΣοΫઃఆͰ͋Δeslint-config- airbnbΛซ༻͢Δͱ͍͍ͱࢥ͍·͢ɻ ▸ FacebookJS੩తܕνΣοΧʔͷFlowซͤͯಋೖ͠ɺ JSʹڧ͍ܕ͚ͱnullඇڐ༰Λ͚ͭΔͱΑΓ҆৺Ͱ͠ΐ͏ɻ
THAT'S IT. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠