redux/examples/shopping_cart を見て学ぶ
redux/examples/shopping-cart at master · reactjs/redux · GitHub
仕様
商品リストとカートがあり、商品をカートに入れることができる
商品は在庫があり、在庫がなくなると、sold out と表示される
カートでは合計金額を表示する
state間の連携について
stateとして、商品情報のproductsとカート情報の cartがある。
カートでは商品IDと個数を保持している。
カートで合計金額と取得したい時に、state:cart内には金額の情報がないので、productsから商品の情報を取得する必要がある。
こういった処理をどこに、どうやって書いていくかというのがreduxでよく解っていないポイント。
今回の例では, reducers/index.js に getTotal関数が実装されていて、exportされ、コンポーネントのmapStateToPropsから呼び出されている。
// reducers/index.js内の合計金額を取得する実装 function getQuantity(state, id) { return fromCart.getQuantity(state.cart, id) } function getProduct(state, id) { return fromProducts.getProduct(state.products, id) } export function getTotal(state) { return getAddedIds(state).reduce((total, id) => total + getProduct(state, id).price * getQuantity(state, id), 0 ).toFixed(2) }
reducerを単純にアクションからstateを生成する役割に加えて、stateからデータを取得する役割を負っている。
複数のstateをまたがったデータを取得する際は、index.jsに定義し、各子stateから必要な情報を取得し、調整して返すようにされている。
この程度の規模のプログラムだと問題なさそうだけど、もう少し大きくなってくるとindex.jsがカオスになりそうなので、もう少し工夫する必要がありそう。
stateの持ち方の工夫
state:productsが単純な配列ではなく、下記のように定義されている。
{ byId: {}, // id => product のオブジェクト。 state.byId[product_id] で商品データにアクセスできる visibilityIds: [] // 商品IDのリスト }
これは一長一短ありそう。
感想
基本理念以外の部分は結構自由に実装されている印象。
FWに従って思考停止ではなく、作るプログラムに合わせて色々考えて工夫する必要がありそう。