Flow & Redux で Reducer の実装パターンを考える

  • 22
    いいね
  • 0
    コメント

背景

段階的に片付けしていく、というFlowのコンセプトで、最も需要が高いのは、純粋なJSで済む状態管理、 とくに Redux の Reducer の部分であると考えられる。

実際のコード

とりあえずこうなるだろうというのを書いてみた。

/* @flow */

// constants
const INCREMENT = 'increment'
const ADD = 'add'

export const Actions = {
  INCREMENT, ADD
}

// actions
export type IncrementAction = {
  type: typeof Actions.INCREMENT
}

export type AddAction = {
  type: typeof Actions.ADD,
  payload: number
}

export type CounterAction = IncrementAction | AddAction

// reducer
type CounterState = { value: number }
export default (state: CounterState = { value: 0 }, action: CounterAction) => {
  switch(action.type) {
     case Actions.INCREMENT:
      console.log(action.payload) //failed
       return { value: state.value + 1 }
     case Actions.ADD:
       return { value: state.value + action.payload }
  }
}

// action creator
export function increment(): IncrementAction {
  return {type: Actions.INCREMENT}
}

export async function incrementAsync(): Promise<IncrementAction> {
  return {type: Actions.INCREMENT}
}

export function add(n: number): AddAction {
  return {type: Actions.ADD, payload: n}
}

switch 式の中の failed と書いてある部分が一番コケてほしい部分。INCREMENTにpayolad はない。で、ちゃんとコケてくれる。

ACTION名の生成にredux-actionsみたいな関数を挟んだりすると、うまくいかない。諦めた方がいい。

ファイルの分割

reducers/
  counter/
    index.js
    actions.js
    constants.js

人次第。なんか規約がほしい。constants.js は actions.js の中に移動しても良さそうだけど、reducer と actions の主従関係が、書いてる人次第だと思う。とりあえず外出した。

フラット派ならこっちだろうか。

actions/
  counter-actions.js
reducers/
  counter.js 

Flowの推論機を壊さない範囲で綺麗にしたい。