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
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
980
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
go-sqletch
moznion
0
140
ソフトウェア ファクトリー - 再現性のあるソフトウェアの工場づくり / Software factory
iktakahiro
6
4.9k
フロントエンドカンファレンス関西2026 - 速すぎるUIに、待ち時間を
teamlab
PRO
0
130
Temporal 最高!でも改めて「日付」について調べたら人類の負債すぎる件
riyaamemiya
0
140
コンテナ運用におけるネットワーク・コンテナコストの削減方法/How to Reduce Network and Container Costs in Container Operations
masakiokuda
1
150
初海外で注意すべきこと12選!!!安全快適なre:invent生活にするために
yuuuuuuu168
1
160
JAWSUG TOHOKU 青森支部 「LoGoチャット」のAWS移行で 乗り越えたこと
taketakekaho
0
330
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
860
パッチ更新でterraform initが落ちた日
grimoh
1
140
TinyGoでオブザーバビリティ?OpenTelemetryはTinyGoで使えるのか / Is OpenTelemetry available in TinyGo environment?
ymotongpoo
2
140
AIにシークレットを見せない、WSL2で安全な開発環境
yazm
0
300
『SAR衛星データ解析入門』のご紹介とその応用
syuchimu
0
120
Featured
See All Featured
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
750
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
940
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
560
How to Think Like a Performance Engineer
csswizardry
28
2.9k
Embracing the Ebb and Flow
colly
88
5.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
580
How to train your dragon (web standard)
notwaldorf
96
6.9k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
380
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