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
MobX の話
Search
kariyayo
July 22, 2017
Programming
390
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
MobX の話
kariyayo
July 22, 2017
More Decks by kariyayo
See All by kariyayo
echoサーバーを書いてI/Oと仲良くなる話
kariyayo
3
890
SpringはどうやってDIしているのか? #jjug_ccc
kariyayo
4
3.7k
Apexで複数環境のLambda関数をデプロイする話 #jawsug
kariyayo
1
2k
近況報告といろいろ作るのが楽しい話 #yokohama_north
kariyayo
0
920
目指せ3つ星インデックス #yokohama_north
kariyayo
2
890
Spring Boot と Swagger #渋谷java
kariyayo
4
5.8k
Gradleを使えるようになるために
kariyayo
0
130
Other Decks in Programming
See All in Programming
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.8k
phperだってパンチカードでコーディングしたい
o0h
PRO
0
450
Apple Intelligenceとオンデバイス時代の到来
yahir0
0
140
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
150
Event is what happens
moro
2
1.6k
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.8k
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
sbt 2.0: takeoff
eed3si9n
0
170
Zero-Tap Sign-In対応、結局何をすればいいの?
mitohato14
0
770
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
180
Modernizing iOS Apps
seyfoyun
0
120
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
200
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Building Better People: How to give real-time feedback that sticks.
wjessup
371
20k
For a Future-Friendly Web
brad_frost
184
10k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
A Tale of Four Properties
chriscoyier
163
24k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.7k
Ruling the World: When Life Gets Gamed
codingconduct
0
420
KATA
mclloyd
PRO
35
16k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.9k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
290
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Transcript
.PC9ͷ 2017/7/22 Yokohama North Meetup ˌ6 #yokohama_north bati (@bati11_ )
3FBDU/BUJWFͰΞϓϦ࡞ͬͨ
• 3FBDU/BUJWF • ͬͯΔϥΠϒϥϦ • XJYSFBDUOBUJWFOBWJHBUJPO SFBDUOBUJWF JOUFSBDUBCMF SFBDUOBUJWFDBMFOEBS SFBDU
OBUJWFTWH FUD • ετΞͲ͏͠Α͏ʁ
• ετΞͲ͏͠Α͏ʁ • 8FCͷํͰ7VFKTͱ7VFYͬͯΔ • 3FEVYͳΜ͔৮Γ৺͕͋Μ·Γͩͬͨ • .PC9ʹͨ͠ • 7VFYʹ৮Γ৺͕͍ۙɺؾ͕ͨ͠
• IUUQTNPCYKTPSH
.PC9ͷલʹ
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } }
Α͔͘Βͳ͍ͷ͕͍Δ
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } アロー構文 IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC +BWB4DSJQU3FGFSFODFBSSPX@GVODUJPOT
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } クラス、コンストラクタ、メソッド IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC +BWB4DSJQU3FGFSFODF$MBTTFT
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } getter IUUQTCBCFMKTJPMFBSOFT FDNBTDSJQUGFBUVSFTNPEVMFT
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } プロパティの省略形 IUUQTEFWFMPQFSNP[JMMBPSHKBEPDT8FC +BWB4DSJQU3FGFSFODF0QFSBUPST0CKFDU@JOJUJBMJ[FS
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } テンプレート文字列 IUUQTCBCFMKTJPMFBSOFTFDNBTDSJQU GFBUVSFTUFNQMBUFTUSJOHT
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } モジュール(export, import) IUUQTCBCFMKTJPMFBSOFTFDNBTDSJQU GFBUVSFTNPEVMFT
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } クラスのプロパティ IUUQTHJUIVCDPNUDQSPQPTBMDMBTTQVCMJDpFMET
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } デコレータ IUUQTHJUIVCDPNUDQSPQPTBMEFDPSBUPST
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } } Flow IUUQTqPXPSH
// @flow import { autorun, observable, action, computed } from
'mobx'; type Task = { task: string, completed: boolean, assignee: ?string, } export default class TodoStore { @observable todos: Array<Task> = []; @observable pendingRequests: number = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount(): number { return this.todos.filter(todo => todo.completed === true).length; } @computed get report(): string { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task: string): void { this.todos.push({task, completed: false, assignee: null}); } }
.PC9Ͱ50%0ετΞ
• ಈ͔͠ͳ͕Βݟ͍͖ͯ·͠ΐ͏ʂ • ಈ͔͢લʹ
GMPXͳ͠Ͱ͍͖·͢
import { autorun, observable, action, computed } from 'mobx'; export
default class TodoStore { @observable todos = []; @observable pendingRequests = 0; constructor() { autorun(() => console.log(this.report)); } @computed get completedTodosCount() { return this.todos.filter(todo => todo.completed === true).length; } @computed get report() { if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } } @action addTodo(task) { this.todos.push({task, completed: false, assignee: null}); } }
.PC9%FW5PPMTΛ ಋೖ͓͖ͯ͠·͢
• .PC9%FW5PPMT • IUUQTHJUIVCDPN[BMNPYJTVTNPCYSFNPUFEFW import { autorun, observable, action, computed
} from 'mobx'; import remotedev from 'mobx-remotedev/lib/dev'; @remotedev export default class TodoStore { ・・・ }
ಈ͔ͯ͠Έ·͢
• ಈ͔͠ͳ͕Βݟ͍͖ͯ·͠ΐ͏ʂ • ಈ͔͢·Ͱͷखॱϒϩάʹॻ͖·ͨ͠ • IUUQCBUJCMPHIBUFOBCMPHDPNFOUSZ
• !PCTFSWBCMFͳϓϩύςΟΛมߋ͢Δͱɾɾɾ • BVUPSVOʹࢦఆͨ͠ॲཧ͕ࣗಈతʹ࣮ߦ͞ΕΔ export default class TodoStore { @observable
todos = []; @observable pendingRequests = 0; constructor() { autorun(() => console.log(this.report)); } ・・・ @action addTodo(task) { this.todos.push({task, completed: false, assignee: null}); } }
• !BDUJPOͳϝιουͰ!PCTFSWBCMFͳϓϩύ ςΟΛมߋ͢Δ • VTF4USJDUΛ͍ͬͯΔͱɺ!BDUJPOͳϝιο υҎ֎Ͱ!PCTFSWBCMFͳϓϩύςΟΛߋ৽ ͍ͯ͠ΔͱɺܯࠂΛग़ͯ͘͠ΕΔ • ݁Ռɺίʔυͷݟ௨͕͠ྑ͘ͳΔ
• !DPNQVUFEͳHFUUFSͷ݁ՌΩϟογϡ͞Ε Δ • DPOTPMFMPHΛॻ͍ͯࢼ͢ͱ͔Δ constructor() { autorun(() => console.log(this.report));
} @computed get report() { console.log("report"); if (this.todos.length === 0) { return "<none>"; } else { return `Next todo: "${this.todos[0].task}". ` + `Progress: ${this.completedTodosCount}/${this.todos.length}`; } }
3FBDU%PN .PC9 Ͱ50%0ΞϓϦ
• NPCYSFBDU • IUUQTHJUIVCDPNNPCYKTNPCYSFBDU • !PCTFSWFS͕͑ΔΑ͏ʹͳΔ • 3FBDUͷ$PNQPOFOUΫϥεʹ!PCTFSWFSΛ ͚ͭΔͱSFOEFSϝιου͕BVUPSVOͷରʹ ͳΔ
• ͭ·Γɺ!PCTFSWBCMFͳϓϩύςΟͷมߋ͕6* ʹө͞ΕΔʂ
• ಈ͔͠ͳ͕Βݟ͍͖ͯ·͠ΐ͏ʂ • ίʔυͪ͜Β • IUUQTHJTUHJUIVCDPN CBUJBC⒎FGGGDEBD
3FBDU/BUJWF .PC9
• 3FBDU/BUJWFͰ5PEP4UPSFͦͷ··͑Δ • 6*ͷ࡞Γํ͕%PN༻ͷ$PNQPOFOU͔ΒωΠςΟ ϒΞϓϦ༻ͷ$PNQPOFOUʹมΘΔ • ελΠϧࣅͯΔ
• ಈ͔͠ͳ͕Βݟ͍͖ͯ·͠ΐ͏ʂ • ίʔυͪ͜Β • IUUQTHJTUHJUIVCDPN CBUJEDGFFECC • 3FBDU/BUJWF%FCVHHFS •
IUUQTHJUIVCDPNKIFOSFBDUOBUJWFEFCVHHFS
·ͱΊ
• .PC9ྑ͍ • .PC9ͷνϡʔτϦΞϧ • IUUQTNPCYKTPSHHFUUJOHTUBSUFEIUNM • ͨΊʹͳΔϒϩάهࣄ • IUUQMFBMPHIBUFCMPKQBSDIJWFDBUFHPSZ.PC9
• ָͰྑ͍ͷ͚ͩͲɺͦͷ໘ɺܾ·ͬͨϨʔϧ ͕ͳ͍ͷͰɺ࠷ॳʹઃܭͪΌΜͱΒͳ͍ͱ࣮ ͢ΔਓʹΑͬͯɺ࣮ͷํ͕όϥόϥʹͳΔ Մೳੑ͕ߴͦ͏ • ࣮ࡍͳΓ͔͚ͨ • ʂʂʂେࣄͳ͜ͱʂʂʂؾΛ͚ͭͳ͍ͱSFOEFS ͕Կճ࣮ߦ͞ΕΔɻˣಡΜͩํ͕ྑ͍
• IUUQTNPCYKTPSHCFTUSFBDUIUNM • IUUQTNPCYKTPSHSFGHVJEFNPEJpFSTIUNM