そんな訳で、前回に続きコンソールでreduxを触っていこうと思います。
action creator
さて、まずは前回同様、単純な数をカウントアップするcounterReducerを作っていきましょう。
ただし、今回は前回と違い、actionに数を指定して、指定した数だけカウントアップするする様にします。
const redux = require('redux');
const counterReducer = (state = { counter: 0 }, action) => {
if (action.type === 'COUNT_UP') {
return { counter: state.counter + action.count };
} else {
return state;
}
};
const storeA = redux.createStore(counterReducer);
これにactionをdispatchすると、以下の様に動作します。
const countActionTwo = { type: 'COUNT_UP', count: 2 };
storeA.dispatch(countActionTwo);
storeA.getState();
// -> { counter: 2 }
const countActionThree = { type: 'COUNT_UP', count: 3 };
storeA.dispatch(countActionThree);
storeA.getState();
// -> { counter: 5 }
countActionほげを毎回定義するの、面倒くさいですね?
actionを返す関数を定義しましょう。
// ↑のコードの続き
const createCountAction = (count) => { return { type: 'COUNT_UP', count }};
storeA.dispatch(createCountAction(10));
storeA.getState();
// -> { counter: 15 }
storeA.dispatch(createCountAction(20));
storeA.getState();
// -> { counter: 35 }
これがactionCreatorです。
middleware
middlewareは、actionの前後に処理を挟み込むための関数です。
storeを生成する際、redux.applyMiddleware
を使ってstoreに登録します。
// ↑のコードの続き
// COUNT_UPアクションが渡ってきた場合、前後の数値を表示するmiddleware
const middleware = store => next => action => {
if(action.type === 'COUNT_UP'){
console.log('before')
console.log(action.count)
console.log(store.getState())
next(action);
console.log('after')
console.log(store.getState())
return
}
next(action)
}
const storeB = redux.createStore(
counterReducer,
redux.applyMiddleware(middleware)
)
storeA.dispatch(createCountAction(10));
// -> before
// -> 10
// -> { counter: 0 }
// -> after
// -> { counter: 10 }
上記の例ではconsole.logを呼んでいるだけですが、storeを操作して別のactionをdispatchしたり、actionを書き換えたりする事もできます。
// countが0だったら{ type:'COUNT_UP' count:1 } をdispatchするmiddleware
const zeroIsOneMiddleware = store => next => action => {
if(action.type === 'COUNT_UP' && action.count === 0){
store.dispatch({ type:'COUNT_UP' count:1 })
}
next(action);
}
// 10以上のCOUNT_UPを無効にする
const denialOverTenMiddleware = store => next => action => {
if(action.type === 'COUNT_UP' && action.count > 10){
const overwriteAction = { type:'COUNT_UP' count:10 }
}
next(overwriteAction);
}
middlewareは複数登録することができ、登録した順にnext()で次のmiddlewareが呼ばれます。
無駄に見た目が複雑になる為掲載は控えますが、興味がある人は複数middlewareを定義して、action実行時どこにあるコードがどのタイミングで呼ばれるかを確認してみて下さい。
最後に
以上がreduxの主要な機能です。1
非同期処理用やviewとの連動、actionのスタイルの統一などなどの課題を解決するため公開されている様々なライブラリを組合わせて使っていくことになります。
とはいえ、redux自体はこのように非常に薄いライブラリです。
コアとなる部分が十全に理解できているのと居ないのでは、周辺ライブラリの理解速度が全然違うので、このようなまとめを書いてみました。
この記事が、皆さんの開発の一助になれば幸いです。
それでは、良いフロントエンドライフを!
-
store.subscribe()は、入門レベルでは使わないと思ったので割愛しました。 ↩