LoginSignup
0
1

More than 5 years have passed since last update.

Redux-Trampoline書いてみた

Last updated at Posted at 2019-01-16

redux-thunk

redux-thunkとは!
functionをdispatchしたら実行してくれる。
それだけのことでAction Creatorであらゆるビジネスロジックを扱える気がするんだ。

redux-thunkのソースコード

redux-thunk
function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

たった14行。extraArgumentの対応を除けばもっと短い。

こういうことでしょ?
export default ({ dispatch, getState }) => next => action => {
  if (typeof action === 'function') {
    return action(dispatch, getState);
  }

  return next(action);
};

再帰呼び出しのtrampoline

https://qiita.com/41semicolon/items/985bdd2f551d9392463c
こちらの記事を参考にしました。

trampoline
function trampoline (fn) {
  return (...args) => {
    let result = fn(...args);
    while (typeof result === 'function') {
      result = result();
    }
    return result;
  };
}

あれ、これって……なんかさっき見たような。

redux-trampoline

てな訳で書いてみました。

redux-trampoline/index.js
export default ({ dispatch, getState }) => next => action => {
  while (typeof action === 'function') {
    action = action(dispatch, getState);
  }

  return next(action);
};

使ってみる

カウントダウンの例は例の記事から拝借しました。

actions/index.js
export const LOG_COUNT = 'LOG_COUNT';

export const countDown = num => dispatch => {
  if (num === 1) {
    return { type: LOG_COUNT, num };
  }
  if (num % 1000 === 0) {
    // 渡されたdispatchを使うと途中経過も送れる
    dispatch({ type: LOG_COUNT, num });
  }

  return countDown(num - 1);
};
reducers/index.js
const result = (state = null, action) => {
  // actionTypeを省略する横着
  return action.num;
};

export default result;
index.js
import { createStore, applyMiddleware } from 'redux';
import trampoline from './redux-trampoline';
import result from './reducers';
import { countDown } from './actions';

const store = createStore(result, applyMiddleware(trampoline));
const unsubscribe = store.subscribe(() => console.log(store.getState()));

store.dispatch(countDown(30000));

unsubscribe();

実行結果

result
30000
29000
28000
27000
26000
25000
24000
23000
22000
21000
20000
19000
18000
17000
16000
15000
14000
13000
12000
11000
10000
9000
8000
7000
6000
5000
4000
3000
2000
1000
1

applyMiddlewareについて

Reduxのチュートリアル本当に素晴らしいんだ。
https://redux.js.org/api/applymiddleware

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1