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
Redux Middleware Wars (Japanese)
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Shuhei Kagawa
July 14, 2016
Technology
2k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Redux Middleware Wars (Japanese)
M3 Tech meetup! #2 ~フロントエンドの副作用~
http://m3-engineer.connpass.com/event/33802/
Shuhei Kagawa
July 14, 2016
More Decks by Shuhei Kagawa
See All by Shuhei Kagawa
Profiling Node.js apps on production
shuhei
0
970
Building a Pixel Art Editor with Elm
shuhei
1
900
Redux Middleware Wars (English)
shuhei
0
220
Draw Animated Chart on React Native
shuhei
0
9k
Angular 2 Offline Compiler
shuhei
0
5.5k
Weird Attractors
shuhei
0
960
Angular 2 @ JS Ojisan #6-3
shuhei
1
3.1k
Introduction to Angular 2
shuhei
2
200
Git の内部データ構造
shuhei
2
2.1k
Other Decks in Technology
See All in Technology
AgentCoreで実践するハーネスエンジニアリング
yakumo
1
290
Incremental HTTP
kazuho
5
2.1k
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
2
390
freeeらしさをAIとともに作る / Creating the freee Experience with AI
ymrl
0
210
契約書画像からの情報抽出に特化した視覚接地モデルを育てる話
sansantech
PRO
1
150
Futexes the good, the bad, the ugly
ennael
PRO
0
130
OSC2026on_the-world-is-waiting-for-your-voice.pdf
naruoga
0
360
AI時代に必要な脅威モデリング― 変化の速度に負けない理解とリスク判断
masakane55
4
1.1k
並行性の問題を防げ!実践トランザクション入門
occhi
0
280
全人類(ほぼ)AWS Organizations の上でAWSを利用している、その世界を知る話
htan
0
120
自律型 AI をセキュアに実装!Gemini と MIG で作る動的コード実行環境
recruitengineers
PRO
1
220
データ品質を壊しながらSnowflakeのAIに分析させてみた
kawanago
0
520
Featured
See All Featured
Amusing Abliteration
ianozsvald
1
330
Building Flexible Design Systems
yeseniaperezcruz
330
41k
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
350
Done Done
chrislema
187
17k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Balancing Empowerment & Direction
lara
6
1.3k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
620
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
610
My Coaching Mixtape
mlcsv
0
340
Transcript
Redux Middleware Wars
Me • So$ware Engineer at M3, Inc. • ҩྍݱͰ͏γεςϜͷ։ൃ •
AngularJS, Rails, Node.js, Babel, etc. • GitHub, Qiita: @shuhei • TwiGer: @shuheikagawa • ! Ϗʔϧݕఆ 2 ڃ
Middleware ʹ͍ͭͯͦ͢ͷલʹɾɾɾ
ͦͦ Redux ͱʁ • Predictable state container for JavaScript apps
• ༧ଌՄೳͳঢ়ଶίϯςφʢ༁ʣ • ͱͱ Time traveling, hot reloading Λతͱͯ͠࡞ΒΕͨ Flux తͳԿ͔
Redux ͷ 3 ݪଇ 1. ΞϓϦͷશঢ়ଶΛҰͭͷ Object (State) ͱͯ͠อ࣋ 2.
Action ΛૹΔʢdispatchʣ͜ͱʹ ΑͬͯͷΈ State ΛมߋͰ͖Δʢͱ͍ ͏͔৽͍͠ State ͕࡞ΒΕΔʣ 3. Reducer ͱ͍͏ pure ͳؔʢಉ͡Ҿ ʹରͯ͠ৗʹಉ͡ฦΓΛฦ͢ʣʹ ΑͬͯͷΈঢ়ଶ͕มߋ͞ΕΔ reducer : (State, Action) -> State
! Pure ͳؔͱʁ • ҾͷΈʹΑͬͯฦΓ͕ܾ·Δ • ؔͷ֎ͷঢ়ଶΛมߋ͠ͳ͍ʢ෭࡞༻͕ͳ͍ʣ
! Pure ͡Όͳ͍ؔ • ࣌ʹΑͬͯฦ͕͢ҧ͏ • ฦΓ͕ͳ͍ • ҾΛมߋͯ͠͠·͏ •
ޙͰίʔϧόοΫ͕ݺΕΔ • etc.
Β͵ؒʹΞϓϦ ͷঢ়ଶ͕มΘΔ͜ ͱ͕ͳ͍
None
ͱ͍͑ɺ෭࡞༻Ͳ͏͢Δͷʁ • AJAX • local storage • cookie • ϩά
• etc.
• Reducer ͷதʹॻ͘: ແཧ • View Component ͷதʹॻ͘: ͔ͤͬ͘ঢ়ଶΛ͍ग़ͨ͠ͷ ʹɾɾɾ
• Ac4on Creator ͷதʹॻ͘: dispatch Λ͢ඞཁ͋Γ
Middleware
Redux Middleware ͱ • dispatch ͷલޙʹॲཧΛڬΉ • Action Λड͚ͯɺΰχϣΰχϣͰ͖ Δ
• Action ΛͪΐͬͱΒͤͯૹΔ • ผͷ Action ʹஔ͖͑Δ • ඇಉظॲཧΛߦ͍ɺ݁ՌΛ Action ͱͯ͠ૹΔ • e.g. WSGI, Rack, Express, Koa, etc.
ྫ: ͳʹ͠ͳ͍ ड͚औͬͨ Ac$on Λͦͷ··࣍ͷ middleware ʹ͛Δ const passthrough =
store => next => action => { return next(action); };
ྫ: ϩάΛग़ྗ ࣍ͷ middleware ʹ ac+on Λ͛ΔʢnextʣલޙͰϩάΛग़ྗ const logger =
store => next => action => { console.log('prev state', store.getState()); console.log('action', action); const returnValue = next(action); console.log('next state', store.getState()); return returnValue; };
ྫ: Promise ͷ݁ՌΛͭ const promise = store => next =>
action => { if (typeof action.then === 'function') { return action.then(store.dispatch); } else { return next(action); } }; function fetchPosts() { return fetch('/posts').then(res => res.json()) .then(posts => ({ type: 'POSTS_FETCHED', posts })); } dispatch(fetchPosts);
ࠓճඇಉظॲཧΛߦ͏ Middleware ʹয
΄͍͠ͷ • ! ςετͷ͢͠͞ʢϞοΫແ͠ͰςετͰ͖Δͱ࠷ߴʣ • " ۭ࣌Λ͑Δʢthro'ling, debouncingʣ • #
ϩδοΫͷڽू • ✨ ։ൃͷ׆ൃ͞
ඇಉظॲཧΛߦ͏ Middleware ಠஅͱภݟʹΑΓ... | ----------------- | ---- | --------- |
---- | ---- | ---- | ---- | | name | star | from | test | time | cohe | acti | | ----------------- | ---- | --------- | ---- | ---- | ---- | ---- | | redux-thunk | 2392 | '15/07/13 | C | C | B | A | | redux-promise | 864 | '15/07/02 | - | C | C | C | | redux-saga | 3172 | '15/11/30 | B | A | A | A | | redux-loop | 641 | '16/01/06 | A | C | B | C | | redux-observable | 634 | '16/02/16 | C | A | B | A | | ----------------- | ---- | --------- | ---- | ---- | ---- | ---- | ⭐ ͷ 2016/7/5 ௐ
redux-thunk ⭐2392 Ac#on ͱͯؔ͠ʢthunkʣ͕དྷͨΒɺͦΕΛ࣮ߦ͢ΔʢҾʹ dispatch ͱ getStateʣ const fetchBeers =
() => (dispatch, getState) => { return fetch('/beers') .then(res => res.json()) .then(items => dispatch('FETCH_BEERS_SUCCEEDED', items)) .catch(error => dispatch('FETCH_BEERS_FAILED', error)); }; dispatch(fetchBeers());
redux-thunk ⭐2392 • ! ϞοΫ͠ͳ͍ͱςετ͕ॻ͚ͳ͍ • " Ac%on ΛҰ͔ͭͮͭ͠ड͚ΒΕͳ͍ͷͰɺdebounce ͳͲ͕
͍͠ • # ΄Ͳ΄ͲʹෳࡶͳϩδοΫॻ͚Δ • ✨ ΄Ͳ΄Ͳʹϝϯς͞Ε͍ͯΔɻͦͦ 13 ߦ͔͠ͳ͍ • ࢀߟ: How to dispatch a Redux ac%on with a %meout?
redux-promise ⭐864 FSA (Flux Standard Ac/on) ͷ payload ͷ promise
Λղܾ͠ɺ Ac/on ͱͯ͠ૹΓͯ͘͠ΕΔ function fetchItems() { const promise = fetch('/items').then(res => res.json()); return { type: 'FETCH_ITEMS', payload: promise }; } dispatch(fetchItems());
redux-promise ⭐864 • ! γϯϓϧͳͷͰɺͦ͜·Ͱςετ͠ͳͯ͘ྑͦ͞͏ • " debounce ͳͲͰ͖ͳ͍ •
# ෳࡶͳϩδοΫॻ͚ͳ͍ • ✨ 4 ϲ݄ఔϝϯς͞Εͯͳ͍ɻ25 ߦ͚͕ͩͩɾɾɾ • Τϥʔॲཧͷൺֱతॏཁͦ͏ͳ MR ͕Ϛʔδ͞Ε͕ͨϦϦʔ ε͞Ε͍ͯͳ͍
redux-saga ⭐3172 Saga ͱݺΕΔ generator (saga) Ͱ෭࡞༻Λ͏ॲཧΛهड़ function* fetchBeer(action) {
try { const beers = yield call(fetchBeer, action.id); yield put({ type: 'FETCH_BEER_SUCCEEDED', payload: beers }); } catch (error) { yield put({ type: 'FETCH_BEER_FAILED', error }); } } function* watchFetchBeer() { yield* takeEvery('FETCH_BEER', fetchBeer); }
redux-saga ⭐3172 • ! ςετ͕͍͢͠ʂʂʂ • ෭࡞༻ϦΫΤετΛ yield ͯ͠ɺmiddleware ʹ࣮ߦͯ͠
Β͍ɺ݁ՌΛड͚औΔ • ࣗ pure ͳ··ෳࡶͳඇಉظॲཧ͕ॻ͚Δ • ৄ͘͠ @kuy ͞Μͷ͓Ͱɾɾɾ
redux-loop (store enhancer) ⭐641 Elm Λਅࣅͨ APIɻreducer ͕ state ͚ͩͰͳ͘
Effects ฦ͢ function beers(state = [], action) { switch (action.type) { case 'FETCH_BEERS': return loop(state, Effects.promise(fetchBeers)); case 'FETCH_BEERS_SUCCEEDED': return action.payload; default: return state; } }
redux-loop (store enhancer) ⭐641 • ! ϞοΫͳ͠ͰςετͰ͖Δ • Effects ͨͩͷ
Objectɻ࣮ߦ͢Δ·Ͱ෭࡞༻ى͖ͳ͍ • " debounce ͳͲͰ͖ͳͦ͞͏ • # Effects ΛΈ߹ΘͤΔ͜ͱ͕Ͱ͖Δ • ✨ 3 ϲ݄΄Ͳϝϯς͞Ε͍ͯͳ͍ɻ࡞ऀ͕ Elm ͔͠ॻ͔ͳ͘ ͳͬͯ͠·ͬͨʁ
redux-observable ⭐ 634 reducer ͷޙͰ Action Λड͚ͯ Action Λग़ྗ͢Δ Observable
Λฦ͢ function beerEpic(action$, store) { const beers$ = action$.ofType('FETCH_ITEMS') .mergeMap(() => Observable.fromPromise(fetchBeers())) .map(beers => ({ type: 'FETCH_BEERS_SUCCEEDED', payload: beers })); return Observable.merge( beers$, something$ ); }
redux-observable ⭐ 634 • ! ϞοΫ͠ͳ͍ͱςετͰ͖ͳ͍ • " Rx ͷڧྗͳ
operator Ͱ༰қʹۭ࣌Λ੍ͤΔ • # redux-saga తͳ background processor style ʹਐԽ • ෳࡶͳॲཧॻ͚Δ • ✨ ݱࡏ։ൃதɻͱͯγϯϓϧ • Rx ΩϚΔͱؾ͍͍࣋ͪʢݸਓͷײʣ
τϨϯυʢʁʣ • σʔλͱͯ͠ͷ෭࡞༻ʢsaga, loop, Cycle.jsʣ • ෭࡞༻ϦΫΤετΛ middleware ͕ॲཧ͢Δ •
։ൃऀ͕ॻ͘ϩδοΫ͕៉ྷʹอͯΔ • Background processor ελΠϧʢsaga, observable, chooʣ • reducer ͷલͰͳ͘ޙͰ Action Λड͚Δ
࠙ձͰ͍Ζ͍Ζڭ͑ͯԼ͍͞ʂ
Thanks!
Credits • Chart of Redux from h0p:/ /www.bebe0erdeveloper.com/coding/ ge=ng-started-react-redux.html