React 入門 (8) ~ TODOアプリを作る(3) ~ Reduxの導入

ある程度 Redux を理解できたので、自分のTODOアプリに組み込んでみる。

Redux インストール

$ npm i --save redux react-redux
$ npm i -D @types/redux @types/react-redux

基本的に前回作ったものをマイグレーションする感じでもってくる。だが、NumberList.tsxdispatch 関数を渡す方法に苦戦した。結局はPropsをinterfaceで定義してそれを型として使うようにした。

interface PropsWithDispatch {
  dispatch: any
}

const NumberList = withStyles(styles)(
  class extends React.Component<PropsWithDispatch & WithStyles<typeof styles>, {}> {
  ...

使うときは this.props.dispatch() として使う。


次に、TODOの完了時の動作を実装する。

まずはアクションから、src/actions/index.tscompleteTodo という関数を追加する

export const completeTodo = (id:number) => ({
  type: 'COMPLETE_TODO',
  id: id,
})

次にレデューサー、src/reducers/todos.tsCOMPLETE_TODOcase を追加する。Redux の Example では 三項演算子を使っていたが、あまり使いたくなかったので、if文で作成した。javascript界隈だと三項演算子はメジャーなのだろうか?

case 'COMPLETE_TODO':
  return state.map(todo => {
    if(todo.id === action.id) {
      return { ...todo, completed: !todo.completed }
    } else {
      return todo
    }
  })

最後に NumberList.tsxon_click_li に ディスパッチャーを使うように変更する

on_click_li = (e: React.MouseEvent<HTMLDivElement>) => {
  var id:number;
  id = +(e.currentTarget.id)
  this.props.dispatch(completeTodo(id));
}

削除ボタンも同じように変更する。大体 COMPLETE_TODO の時と同じなので省略。


最終的には以下のようになった。(動作はRedux使う前と変わらない)

f:id:bamch0h:20190201223638g:plain
React + Redux + TypeScript + Material UI


成果物は以下にアップしている。

GitHub - bamchoh/react-study at 2019-02-01_add_redux