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
Redux Middleware Wars (Japanese)
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Shuhei Kagawa
July 14, 2016
Technology
8
1.9k
Redux Middleware Wars (Japanese)
M3 Tech meetup! #2 ~フロントエンドの副作用~
http://m3-engineer.connpass.com/event/33802/
Shuhei Kagawa
July 14, 2016
Tweet
Share
More Decks by Shuhei Kagawa
See All by Shuhei Kagawa
Profiling Node.js apps on production
shuhei
0
940
Building a Pixel Art Editor with Elm
shuhei
1
850
Redux Middleware Wars (English)
shuhei
0
200
Draw Animated Chart on React Native
shuhei
0
8.9k
Angular 2 Offline Compiler
shuhei
0
5.5k
Weird Attractors
shuhei
0
920
Angular 2 @ JS Ojisan #6-3
shuhei
1
3.1k
Introduction to Angular 2
shuhei
2
170
Git の内部データ構造
shuhei
2
2.1k
Other Decks in Technology
See All in Technology
作るべきものと向き合う - ecspresso 8年間の開発史から学ぶ技術選定 / 技術選定con findy 2026
fujiwara3
7
2.1k
Eight Engineering Unit 紹介資料
sansan33
PRO
1
6.9k
JAWS DAYS 2026 CDP道場 事前説明会 / JAWS DAYS 2026 CDP Dojo briefing document
naospon
0
190
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
44k
Exadata Database Service on Dedicated Infrastructure(ExaDB-D) UI スクリーン・キャプチャ集
oracle4engineer
PRO
7
7.1k
Serverless Agent Architecture on Azure / serverless-agent-on-azure
miyake
1
150
マルチロールEMが実践する「組織のレジリエンス」を高めるための組織構造と人材配置戦略
coconala_engineer
3
430
ブラックボックス観測に基づくAI支援のプロトコルのリバースエンジニアリングと再現~AIを用いたリバースエンジニアリング~ @ SECCON 14 電脳会議 / Reverse Engineering and Reproduction of an AI-Assisted Protocol Based on Black-Box Observation @ SECCON 14 DENNO-KAIGI
chibiegg
0
140
Oracle Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
4
1.6k
Lookerの最新バージョンv26.2がやばい話
waiwai2111
1
160
Startups on Rails: 2026 at RubyConf Thailand
irinanazarova
0
120
白金鉱業Meetup_Vol.22_Orbital Senseを支える衛星画像のマルチモーダルエンベディングと地理空間のあいまい検索技術
brainpadpr
2
220
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
140
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
140
Navigating Team Friction
lara
192
16k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
180
Game over? The fight for quality and originality in the time of robots
wayneb77
1
130
Faster Mobile Websites
deanohume
310
31k
The Curious Case for Waylosing
cassininazir
0
260
Paper Plane (Part 1)
katiecoart
PRO
0
5.1k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.4k
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