Posted at

Reduxさわってみたのでメモ 【とりあえず動くまで】

More than 3 years have passed since last update.

現在業務で実装しているReactを用いたデモ的なものにReduxを導入してみたので、自分なりに理解したものをメモしておく。


Reduxとは

https://github.com/rackt/redux

Fluxフレームワークの1つで、現時点(2015/9末)でもっともstar数の多いもの。ちなみにAngular用にng-reduxというのがあったりもする


参考サイト

http://rackt.github.io/redux/


インストール

npm install --save react-redux


登場人物


Store



  • stateをもっている


  • Actionをdispatchする

  • Reduxを用いたアプリケーションではStoreは1つしか存在しちゃいけない


Reducer



  • stateがどのように変更されるのかをActionを通して特定するもの

  • 分割可能(reducer composition)


Action



  • Storeに送られる情報


  • Object型であり、Actionを特定するString型のtypeプロパティを必ずもつ


Provider


  • ルートのコンポーネントを囲うもの。こうすることで、コンポーネント内でStoreを利用できるようにする

  • 内部的にはReactcontextという機能を利用しているとのこと


メモ



  • Providerについては、データフローの一連の流れとは関係ないものという認識。なので、Store等と並列に書くのは紛らわしいかもしれない。


  • ReducerというのがFluxそのものの中では出てこない考えなので少し戸惑ったけれど、Storeの役割の一部を切り出したものという認識


実装

まだES6を全然キャッチアップできておらず、ちょいちょい古い書き方が混ざっています(とくにモジュール化)。とはいえ逆に同じ状況の人いるかもしれないので、あえてそのままで書いてみます(汗)


Action


actions.js

var Actions = {}

Actions.UPDATE_LIST = 'UPDATE_LIST';
Actions.DONE_ITEM = 'DONE_ITEM';

Actions.updateList = function(list) {
return { type: Actions.UPDATE_LIST, list };
}

Actions.doneItem = function(itemId) {
return { type: Actions.DONE_ITEM, itemId };
}



Reducer


reducer.js

var Reducer = function(state = [], action) {

switch (action.type) {
case Actions.UPDATE_LIST:
return { list: action.list };
case Actions.DONE_ITEM:
return { itemId: action.itemId };
default:
return state;
}
}

ActionReducerはコンポーネントとの依存はないので、そこは一切気にせずひたすら書いていく


Store, Provier

Mainがルートコンポーネント


Main.js

window.store = createStore(Reducer);

React.render(
<Provider store={store}>
{() => <Main />}
</Provider>,
document.getElementById('content')
);

function mapStateToProps(state) {
return {
itemList: state.list
};
}

Main = connect(mapStateToProps)(Main)



dispatch

ItemCellは子コンポーネントの1つ


ItemCell.js

  onClick: function() {

var list = []; // たとえばAjax通信で取得したリストデータ
store.dispatch(Actions.updateList(list));
},


補足

ひっそりとconnectという処理が入っているけれど、書き方含め(ドットチェーンで繋ぐとかならわかりやすいけど括弧が連続で繋がっていく)これが一番自分としてはわかりづらかった。

Reduxとコンポーネントを文字通り「連結する(connect)」処理には違いないけど、内部的な処理とかはまた追い追い調べたいと思う


よくわかっていないところ



  • connectでリスナの登録など行っているわけだけど、store.subscribe(listener)という書き方は基本しないという考えでいいのかな??


  • store.dispatch()で今回dispatchしているけれど、bindActionCreatorsを使うほうがいい??


所感


  • 上の「よくわかっていないところ」に書いたように、いろいろな書き方ができるような印象があって、どう書くのがいいのか迷うことがある

  • 「子コンポーネントについては一切手をいれなくていい」といったふれこみをどこかで聞いた気がするのですが、そこは確かにそうだと思った


次の課題


  • 大規模開発に備えてActionとかReducerの分割を行う


  • Middlewareとかさわってみる

  • ルーティングの処理を入れる(少し試してみたがうまくいかなかった!!)

  • 今回書いたもので間違っていること・情報不足していることあれば補足する