Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
イカリング2におけるシングルページアプリケーション
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
cockscomb
October 02, 2017
Programming
7.7k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
イカリング2におけるシングルページアプリケーション
cockscomb
October 02, 2017
More Decks by cockscomb
See All by cockscomb
はてなアカウント基盤 State of the Union
cockscomb
1
1.4k
jq at the Shortcuts
cockscomb
1
2.1k
GraphQL放談
cockscomb
4
2.2k
GraphQL Highway
cockscomb
28
8.8k
吉田を支える技術
cockscomb
0
2.6k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.5k
ユーザインターフェイスと非同期処理
cockscomb
5
2.1k
GUIアプリケーションの構造と設計
cockscomb
10
10k
あなたの知らない UIKit の世界 — UITableView に UITextView を置きたい
cockscomb
1
7.6k
Other Decks in Programming
See All in Programming
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
190
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
190
AIが無かった頃の素敵な出会いの話
codmoninc
1
390
「人を評価する AI」の設計と実装
ryoyanara
0
180
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
400
数百円から始めるRuby電子工作
tarosay
0
140
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
210
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
200
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
380
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
160
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
Featured
See All Featured
Leo the Paperboy
mayatellez
8
2.1k
Designing for Timeless Needs
cassininazir
1
430
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
The Curious Case for Waylosing
cassininazir
1
450
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
4 Signs Your Business is Dying
shpigford
187
22k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
330
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
460
Building Applications with DynamoDB
mza
96
7.2k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
360
Transcript
ΠΧϦϯάʹ͓͚Δ γϯάϧϖʔδΞϓϦέʔγϣϯ
id:cockscomb Ճ౻ਘथ גࣜձࣾͯͳ γχΞΞϓϦέʔγϣϯΤϯδχΞ ΠΧϦϯάͷ5FDI-FBE
/JOUFOEP
ΠΧϦϯά w /JOUFOEP4XJUDI0OMJOFΞϓϦ෦ͷαʔϏε w 4QMBUPPOͷϓϨΠσʔλΛݟΔ͜ͱ͕Ͱ͖Δ
࠾༻ٕज़ w ϑϩϯτΤϯυ41" w 5ZQF4DSJQU w 3FBDU 3FEVY w ཪଆʹΦʔέετϨʔγϣϯͱͯ͠ͷ"1*αʔόʔ
w 1FSM w %PDLFSͰಈ͍͍ͯΔ
લఏ w ͳΜͰͰ͖ΔνʔϜ w 8FCΞϓϦέʔγϣϯ w J04"OESPJEͷωΠςΟϒΞϓϦ w 41"ॳΊͯ w
σβΠφʔ͕3FBDU$PNQPOFOUΛ৮ΕΔ
w ٕज़બఆ w 3FBDUͱ3FEVYʹΑΔεςʔτϑϧΞϓϦέʔγϣϯ w 3FEVY4BHB w 8FCϖʔδͱͯ͠ͷ41"
ٕज़બఆ
41"ʹ͢Δཧ༝ w /JOUFOEP4XJUDI0OMJOFΞϓϦͷαʔϏε w ΞϓϦʹظ͞ΕΔϦονͳମݧ w J04"OESPJEͷ8FC7JFXͰදࣔͰ͖ΕΑ͍
41"ʹ͢Δཧ༝ w αʔϏεͷಛੑ w ࠶๚͕ଟ͍ ˠΫϥΠΞϯταΠυΩϟογϡͷޮՌ͕ߴ͍ w 17ηογϣϯൺ͕େ͖͍ ˠॳճͷಡΈࠐΈΑΓͦͷޙͷମݧΛॏࢹ
Ұൠతʹ41"Λ࠾༻Ͱ͖Δ͔ w 41"ʹ͢ΔϢʔβʔϝϦοτͱ։ൃͷఱṝ w ఆ͞ΕΔར༻ύλʔϯ͕41"ʹϚον͢Δ͔ w ηογϣϯɺ17ηογϣϯ͕ଟ͚Ε૬ੑ͕͍͍ w ݕࡧ4/4͔ΒͷϏδλʔ͕ଟ͚ΕॳճͷಡΈࠐΈΛૣ͘͢Δ w
αϙʔτରͷϒϥβ w 4&0ͷॏཁੑ
࠷ޙ༐ؾ w ͍ͥͬͨʹࣗͰͳΜͱ͔͢Δܾҙ
3FBDUͱ3FEVYʹΑΔ εςʔτϑϧΞϓϦέʔγϣϯ
εςʔτϑϧΞϓϦέʔγϣϯ w )551ϦΫΤετʹରͯ͠)551ϨεϙϯεΛฦ͢ ˠεςʔτϨε w σʔλϕʔεͰӬଓԽ w ηογϣϯʹΑͬͯ࿈ଓੑΛอͭ w 41"(6*ΞϓϦέʔγϣϯ
ˠεςʔτϑϧ
Component Props Component Component Component Component Component Virtual DOM Virtual
DOM Virtual DOM Props Props 3FBDU w ΞϓϦέʔγϣϯ $PNQPOFOUͷू߹ମ w $PNQPOFOUೖྗΛݩʹ ৽ͨͳ$PNQPOFOUΛग़ྗ͢Δ ؔͱΈͳͤΔ w ࠷ऴతʹ%0.$PNQPOFOUΛ ग़ྗ͢Δ
σʔλϑϩʔ w 1SPQT ˠ֎෦͔Βͷೖྗ w 4UBUFT ˠ$PNQPOFOUͷঢ়ଶ w $POUFYU ˠࢠଙ$PNQPOFOUʹΘΔঢ়ଶ
࣌ࠁ import * as React from 'react'; interface TimeProps {
time: Date, } export const Time: React.SFC<TimeProps> = ({time}) => { return <time dateTime={time.toISOString()}>{time.toLocaleString()}</time>; };
ͭͷ$PNQPOFOU w 4UBUFMFTT'VODUJPOBM$PNQPOFOU w 1VSF$PNQPOFOU w $PNQPOFOU
4UBUFMFTT'VODUJPOBM$PNQPOFOU w ؔ w ঢ়ଶΛ࣋ͨͳ͍ Component Props Component Component Props
1VSF$PNQPOFOU w Ϋϥε w ঢ়ଶΛ࣋ͭ w 4UBUFTJNNVUBCMFͳΦϒδΣΫτ Component Props Component
Component Props States
$PNQPOFOU w Ϋϥε w ঢ়ଶΛ࣋ͭ w 4UBUFTJNNVUBCMFͱݶΒͳ͍ Component Props Component
Component Props States
ͭͷ$PNQPOFOU w 4UBUFMFTT'VODUJPOBM$PNQPOFOU͕࠷୯७ w 1VSF$PNQPOFOUΛ͏͜ͱ͕ଟ͍
*NNVUBCMF w σʔλ͕JNNVUBCMFͰ͋Δํ͕߹͕͍͍ w ݹ͍ͱ৽͍͕͠ಉ͡ͳΒԿ͠ͳ͍͍ͯ͘ w *NNVUBCMFͳΦϒδΣΫτ===ͰൺֱͰ͖Δ
*NNVUBCMF w 0CKFDUBTTJHO const newObj = Object.assign({}, oldObj, { key:
value }) w 4QSFBE0QFSBUPS const newObj = { ...oldObj, key: value } w *NNVUBCMFKT
Store Reducer State Action dispatch subscribe 3FEVY w ୯Ұͷ4UPSFʹશͯͷঢ়ଶ w
TVCTDSJCFͰมԽΛݕͰ͖Δ w 0CTFSWFSύλʔϯ w ঢ়ଶΛม͍͑ͨͱ͖ 4UPSFʹ"DUJPOΛૹΔ w 3FEVDFS͕"DUJPOʹԠͯ͡ ঢ়ଶΛมߋ͢Δ
"DUJPOϝιουσΟεύον w "DUJPOϝιουͱύϥϝʔλΛ߹Θͤͨͷ w "DUJPO$SFBUPSͱݺΕΔϑΝΫτϦʔؔͰ࡞Δ w 3FEVDFS4UPSFΛมߋ͢ΔͨΊͷϨγʔό w DPNCJOF3FEVDFSTͰෳͷ3FEVDFSΛΈ߹Θͤͯ 4UPSFΛׂ౷࣏͢Δ
3FBDU3FEVY Component Component Component Component Virtual DOM Virtual DOM Virtual
DOM Props Props Component Component
3FBDU3FEVY Connected Provider Connected Component Component Component Component Virtual DOM
Virtual DOM Virtual DOM Props Props Component Component
3FBDU3FEVY w 1SPWJEFS͕DPOUFYUͰ4UPSFΛࢠଙ$PNQPOFOUʹఏڙ w DPOOFDUؔͰ$PNQPOFOUΛ4UPSFͱଓ w 4UPSFΛTVCTDSJCFͯ͠1SPQTʹม͢Δ w ΠϕϯτΛ"DUJPOͱͯ͠4UPSFʹ͑Δ w
ˠ%*
࣌ࠁ import * as React from 'react'; interface TimeProps {
time: Date, } export const Time: React.SFC<TimeProps> = ({time}) => { return <time dateTime={time.toISOString()}>{time.toLocaleString()}</time>; };
࣌ࠁ import * as React from 'react'; import {connect} from
'react-redux'; interface TimeProps { time: Date, } const Time: React.SFC<TimeProps> = ({time}) => { return <time dateTime={time.toISOString()}>{time.toLocaleString()}</time>; }; export default connect(state => ({ time: state.time }))(Time);
3FEVY w ΞϓϦέʔγϣϯશମͷঢ়ଶ w 0CTFSWFSύλʔϯͱ%* w 4UPSFͷઃܭ͕ॏཁ w 3FEVDFSͷΈ߹ΘͤͰׂ౷࣏ w
Կ͔3FEVYͷ4UPSFʹೖΕΔඞཁͳ͍
8FC"1*ͷϨεϙϯε w 3FEVYͷ4UPSFʹͲ͏อ࣋͢Δͷ͔ w ϦιʔεͷεςʔτϚγϯ w ະऔಘɾ௨৴தɾऔಘࡁΈɾऔಘࣦഊ w RemoteResource<T, E>
3FNPUF3FTPVSDF5 & empty pending resolved<T> failed<E> request succeeded failed reload
reload
3FNPUF3FTPVSDF5 & w latestValueͱͯ͠࠷ޙͷΛอ͓࣋ͯ͘͠ w Ϧϩʔυதʹ͕ফ͑ͳ͍ w औಘʹޭͨ࣌͠ࠁอ͓࣋ͯ͘͠ͱศར w ߴ֊ؔ
RemoteResource<T, E>.map<U>((T) -> U) -> RemoteResource<U, E>
3FNPUF3FTPVSDF5 & enum State { EMPTY = "empty", PENDING =
"pending", RESOLVED = "resolved", FAILED = "failed", } abstract class RemoteResource<T, E> { abstract state: State; abstract latestValue: T | null; abstract error: E | null; }
3FNPUF3FTPVSDF5 & w ݱࡏͷঢ়ଶʹΑΒͣ࣍ͷঢ়ଶΛද͢Έ࡞Δ RemoteResource<T, E>.apply(Next<T, E>) -> RemoteResource<T, E>
w "DUJPOʹNext<T, E>͚ͩ࣋ͨͤΔ w 3FEVDFS͕apply͢Δ
3FEVY4BHB
3FEVY w 3FEVYঢ়ଶͷཧʹಛԽ͍ͯ͠Δ w ࡞༻ w ݱ࣮ͷΞϓϦέʔγϣϯ෭࡞༻Λ࣋ͭ
3FEVY4BHB w 3FEVYNJEEMFXBSF w ෭࡞༻ඇಉظੑΛղܾ͢Δ w (FOFSBUPSGVODUJPO
࣌ࠁ const updateTime = createAction('UPDATE_TIME', (time: Date) => ({ time:
time })); const timeReducer = handleAction(updateTime, (state, action) => action.payload!.time, new Date() ); function * ticktack() { while (true) { yield put(updateTime(new Date())); yield delay(1000); } } function * rootSaga() { yield all([ fork(ticktack), ]); }
࣌ࠁ const sagaMiddleware = createSagaMiddleware(); const store = createStore( combineReducers({
time: timeReducer, }), applyMiddleware(sagaMiddleware) ); sagaMiddleware.run(rootSaga);
࣌ࠁ import * as React from 'react'; import {connect} from
'react-redux'; interface TimeProps { time: Date, } const Time: React.SFC<TimeProps> = ({time}) => { return <time dateTime={time.toISOString()}>{time.toLocaleString()}</time>; }; export default connect(state => ({ time: state.time }))(Time);
3FEVY4BHB w 8FC"1*ͷΞΫηε w takeF⒎FDUͰGetSomeRequested"DUJPOΛͭ w ϦΫΤετ͢Δ w putF⒎FDUͰSomeRecieved"DUJPOΛ͛Δ
8FCϖʔδͱͯ͠ͷ41"
8FCϖʔδͱͯ͠ͷ41" w 41"8FCϒϥβͰಈ࡞͢Δ w 8FCϒϥβʹ8FCಛ༗ͷࣄ͕͋Δ w 63- w )JTUPSZ
63- w 3FBDU3PVUFSW w શͯͷϖʔδʹ63-ΛׂΓৼΔ w MPDBUJPOͷมԽʹԠͯ͡$PNQPOFOUΛΓସ͑Δ w ։ൃதʹϦϩʔυͰ͖ͯศར w
(PPHMF"OBMZUJDTͳͲͱ૬ੑ͕Α͍
)JTUPSZ w ϒϥβͷʮΔʯલͷॴʹΔ w φϏήʔγϣϯͷʮΔʯϘλϯ w ҙຯ্ͷ্Ґ֊ʹͬͯ΄͍͠ w ͦ͜Ͱ͞ΒʹϒϥβͷʮΔʯΛԡͨ͠Βʁ Δ
)JTUPSZ w ʮΔʯઌ͕લͷϖʔδͳΒ window.history.back() w ʮΔʯઌ͕લͷϖʔδͰͳ͚Ε window.history.replaceState() A1 A2 A3
B1 B2 C1 C2 A1 A2 B2
)JTUPSZ w MPDBUJPOʹIJTUPSZTUBUFؚΊΔ w QVTI4UBUFͰIJTUPSZTUBUFʹલ ͷMPDBUJPOΛอଘ͢Δ w IJTUPSZTUBUFʮΔʯʮਐΉʯ Ͱ෮ݩ͞ΕΔ w
ৗʹલͷϖʔδ͕ಘΒΕΔ export interface Location { pathname: Pathname; search: Search; state: LocationState; hash: Hash; key: LocationKey; } window.history.pushState({ lastLocation: location, }, "A2", "/a/2");
·ͱΊ
w 41"(6*ΞϓϦέʔγϣϯ w ঢ়ଶͷཧ͕ॏཁ w 3FBDU 3FEVYͳͲΛ͏·͘͏ w ߴͳϢʔβʔΠϯλʔϑΣʔεΛ࣮ݱͰ͖Δ