[Redux] actionがどのようにserializer, stateを探し当てるか
reduxの勉強をしていて、action => reducer => store => componentの流れは理解できたのですが、
実際に実装してみるとこんがらがってしまったので、1つ1つ流れをまとめておきます
1. 各reducerがcombineReducersによってroot.reducerに関連づけられる
// root.reducer.js
import { combineReducers } from 'redux'
import userReducer from '../redux/user/user.reducer'
import cartReducer from '../redux/cart/cart.reducer'
const rootReducer = combineReducers({
user: userReducer,
cart: cartReducer
})
このような関連ができる
user.reducer, cart.reducer => root.reducer
※これからuser.reducer, cart.reducerなどはまとめてeach_reducerと呼びます
2. root.reducerがstoreに関連づけられる
// store.js
import { createStore } from 'redux'
import rootReducer from '../redux/root.reducer'
const store = createStore(rootReducer)
このような関連ができる
root.reducer => store
3. storeがApp全体に関連づけられる
// index.js
import { Provider } from 'react-redux'
import store from '../redux/store'
<Provider store={store}>
<App />
</Provider>
このような関連ができる
App => store => root.reducer => each_reducer
ここまででApp全体(各Component)からeach_reducerにアクセス可能な関連付けができる
しかし、ここではまだ各storeのactionsが関連づけられていない
ではどこで関連づけるか?
A. そのstoreのstate, actionを呼び出したいComponentにおいて、actionとそのComponentを関連付ける(connectを使用)
既にApp(各Component)からstore, reducerまでは関連づいているので、
actionとComponentを関連付ける
4. actionとComponentを関連づける
// header.component.jsx
import { connect } from 'redux'
import { toggleCartHidden } from '../../cart/cart.actions/'
// 3. connectしたので、props.hidden, props.toggleCartHiddenで呼び出せる
const Header = (props) => (
<div>...</div>
)
// 1. ここには呼び出したいstateを登録する
const mapStateToProps = ({ cart }) => ({
hidden: cart.state.hidden
})
// 1. ここには呼び出したいactionを登録する
const mapDispatchToProps = (dispatch) => ({
// toggleCartHiddenはcart.actionsのアクションなので、
// cart.reducerの引数actionに渡される
toggleCartHidden: () => dispatch(toggleCartHidden)
})
// 2. 上記で登録したstateやactionをこのComponentに関連づけて、
// propsから取得できるようにする
export default connect(mapStateToProps, mapDispatchToProps)(Header)
これにより、下記のような関連付けができる
action => Component => App => store => root.reducer => each_reducer
これがactionが呼ばれてからreducerを探し当てるまでの流れ
cartのstateが参照されたらstoreから探し当てるし、cartのactionが呼ばれたらcart.reducerを探し当てて、その引数(action)にわたす
まとめ(actionがreducerを探し当てるまで)
action => Component => App => store => root.reducer => each_reducer
どのような関数を使ってお互いを接続しているかも示すと、下記のようになる
ex) action => (connect) => Component
=> 「actionとComponentをconnectを使って接続している」
action => (connect) => Component => App => (Provider) => store
=> (createStore) => root.reducer => (combineReducers) => each_reducer
Discussion