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
400
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
930
目指せ3つ星インデックス #yokohama_north
kariyayo
2
890
Spring Boot と Swagger #渋谷java
kariyayo
4
5.9k
Gradleを使えるようになるために
kariyayo
0
130
Other Decks in Programming
See All in Programming
Materialが消えた日 〜真っ白なFlutterキャンバスにRenderObjectで絵を描く〜
umigishiaoi
0
150
Crash Auto Pipelines
veronikapj
1
350
Seven New Principles of Software Engineering
yegor256
0
450
Snowflake Openflow Connector利用の勘所 / 20261024developersio2026tokyo-snowflake-openflow
kasacchiful
PRO
0
300
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
230
あなたの await、OS まで届いてる? strace で覗く JavaScript の非同期
hasutosasaki
1
2.2k
Kawaiicon: Kubernetes, it's no longer cool, but let's secure it anyway!
barnbarn
0
110
AI時代のシニアエンジニアとは
yosuke_furukawa
PRO
14
11k
flutter_test のその先へ — Flutter アプリの LLM 機能に「評価」という品質保証を
kosukesaigusa
0
180
느린 네트워크와 저사양 디바이스 사용자를 위한 웹뷰 로딩 시간 개선기
kmkim
1
190
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
410
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
Featured
See All Featured
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.9k
Facilitating Awesome Meetings
lara
57
7.2k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
340
Paper Plane
katiecoart
PRO
5
55k
The Curse of the Amulet
leimatthew05
3
17k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
570
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
370
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
520
Documentation Writing (for coders)
carmenintech
77
5.6k
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