LoginSignup
160
149

More than 5 years have passed since last update.

Redux初めて触って色々わかったメモ

Last updated at Posted at 2015-09-07

最初思ってたこと vs 現実

  • 思ってたこと:なんか軽量?
    • 現実:誤解だった。割りと作ってくと大きめになってくる。軽量感は無い
    • が、redux本体のコードは結構薄い。本当に関数群だけ提供しているイメージ
  • 思ってたこと:他のfluxと圧倒的に違う?
    • 現実:これも誤解。構成としては色々作りこむと最終的には一般的なfluxと同じ感じになる(flummoxとかmartyあたりと体感一緒になる)
    • ActionとかActionCreatorとかその辺が一緒になってくる。
  • 思ってたこと:ES6で圧倒的に書ける?
    • 現実:正解。圧倒的にES6を前提にしている。
  • 思ってたこと:React用のもの?
    • 現実:別にそうでもない。react-reduxを使うことでreactで使えるようになる。

詰まった所など

用語編

割りと初めて見たりする用語に出会った

  • ActionCreator
    • martyあたりにもあった。{type: "HOGE", name: "fuga"}みたいなactionを返すためのwrapper関数とでも考えるとよさそう
  • Reducers
    • 前はStoresと呼ばれていた。
    • (previousState, action) => newStateをするやつ
      • といわれるだけだと謎だが、実際そうだった。
    • Store関連の話と併せて後述するので参照されたい。
  • containers
    • これは用語としていいのかわからない。俗語に近い気がする
    • examplesに結構出てくる
    • reactの起点ポイントをcontainerとしているっぽく見える

Storeの色々編

StoreとReducer

普通のfluxのことを思い浮かべると、Storeはこんな感じでリソースに対して記述するよなものをイメージしていた。

class UsersStore extends Marty.Store {
  constructor(options) {
    super(options);
    this.state = [];
    this.handlers = {
      addUser: Constants.RECEIVE_USER
    };
  }
  addUser(user) {
    this.state.push(user);
    this.hasChanged();
  }
}

が、reduxだとこうならない。
Storeは結構隠蔽されている感じで、利用者はreducerというのだけを記述する(このへんからreducerの話)

reducerは例えばこんな感じ。

function someReducer(state, action) {
  switch (action.type) {
  case SOME_ACTION:
    return Object.assign({}, state, {
      some: action.someValue
    });
  default:
    return state;
  }
}

初見で「どういうこと?」ってなったが、stateが他のFluxの例でのstoreの内部管理されていたような保持される変数だと思えば良い。これが(previousState, action) => newStateしている部分になる。
Reducerは actionに応じてstateを変更する関数 だと思えば良さそう。

ハマりどころ:reducerはstateを変更しないと変更が通知されない

先ほどのサンプルで、わざわざObject.assign({},state, {someProps}) のような小めんどくさいことをしている。

これは理由がある。
例えばこんなreducerの場合、viewが変更されない。

動かないパターン.js
function someReducer(state, action) {
  switch (action.type) {
  case SOME_ACTION:
    state.someValue = action.someValue
    return state;
  default:
    return state;
  }
}

stateを新規に作らないと更新されない。
正直どういう仕組でこうなっているのかちゃんと追えてない。追いたい。

細かい関数色々出ていて焦る編

色々出てきてビビる。が、一個一個は別に大したことをしていない。逆に言うとReduxはここに挙げる関数が全てだった(コード読んでみると結構小さい)

ざっくりと何やってるかを早見表的に。
詳細はAPIリファレンスを参照のこと。

redux編

  • createStore
    • container層で使う。
    • reducerの関数群からstoreを生成する。
    • storeに直接お目にかかれるのはこのあたり。
  • bindActionCreators
    • export functionで定義した関数群のactionCreatordispatcherをbindしてくれる。わりと名前通り
    • Componentの一部で、storeから取り出したdispatchとactionCreatorをつなぐ利用イメージ
  • applyMiddleware
    • いわゆるplugin機構。
    • redux自体が薄めに作られているので、各関数に手をいれるような事はmiddlewareで行う
    • 例えばasyncなactionを扱う機能なども本体ではなく、middlewareとして切りだされている。
    • 結構この仕組みのお陰でredux本体がコンパクトになっているように見える。
  • combineReducers
    • 複数のreducerをまとめて一つのreducerにしてくれる
    • 全く関連のないようなreducerが一個のファイルにあるみたいな状態だと肥大化する一方なので、そういう時に分割しとけば便利

react-redux編

結構「なにそれー」ってなった。
くわしくはこちら

  • connect
    • reduxから渡されるstateと、React.Componentのpropsのマッピングをする部分。
    • マッピングの定義は第一引数で関数として渡す。
connectの例.js
function mapStateToProps(state) {
  return { todos: state.todos };
}

export default connect(mapStateToProps)(TodoApp);
  • <Provider>
    • あえてタグ形式で書いたのは、React.Component継承なもののため。
    • 使うときには下記のような何か魔術的な記載をする(ここも深く追ってない)
    • 下記の例の<App/>部分は、connectでstoreと連結されている必要がある(でないとうまく動かぬ)
Provierの例.js
<Provider store={store}>
  {() => <App/>}
</Provider>

参考

160
149
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
160
149