Django+Reactで学ぶプログラミング基礎(31): Reduxチュートリアル(Todoアプリの要件定義と設計)

##### [前回] [Django+Reactで学ぶプログラミング基礎(30): Reduxチュートリアル(概念とデータフローの詳細)](https://qiita.com/mingchun_zhao/items/c9ea1251cf66f2694e6b)

## はじめに

前回まで、Reduxの概念とデータフローを深掘りしました。
今回から、Reduxを用いてTodoアプリ作成に取り組みます。

## 今回の内容

[Todoアプリの構築](https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers)

- スターター(starter)プロジェクトを設定
- Todoアプリの要件定義
- Todoアプリの設計
    - stateの値を設計
    - stateの構造を設計

## 準備

### [スタータープロジェクト](https://github.com/reduxjs/redux-fundamentals-example-app)をcloneし、設定

- スタータープロジェクトには、以下が事前構成されている
    - Reactの設定
    - デフォルトのスタイル
    - APIリクエストを記述するためのREST API

- VS Codeの、`ファイル`メニューから`フォルダーを開く`を選択
    - プロジェクトのフォルダーを選択(ここでは、`C:\kanban\todo`)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/e7cfad01-c140-a891-0e6f-1059e77d1b86.png)

- `Ctrl + @`で、ターミナルを開き、GitHubからスタータープロジェクトをclone
```
C:\kanban\todo>git clone https://github.com/reduxjs/redux-fundamentals-example-app
```

- `redux-fundamentals-example-app`フォルダーに移動し、プロジェクトに必要なツールをインストール
```
C:\kanban\todo>cd redux-fundamentals-example-app
C:\kanban\todo\redux-fundamentals-example-app>npm install
```

- プロジェクトを起動
```
C:\kanban\todo\redux-fundamentals-example-app>npm start
```

- ブラウザが開き、アプリ画面が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/448b1262-2527-55fa-fd59-ea4512634b75.png)


### プロジェクトの初期状態

- スタータープロジェクトは、標準のCreate-React-Appプロジェクトテンプレートに基づいている
    - いくつかの変更が加えられている

#### プロジェクトの構成
- `/src`
    - `index.js`: アプリのエントリポイントで、メインの`<App>`コンポーネントをレンダリング
    - `App.js`: アプリのメインコンポーネント
    - `index.css`: アプリのスタイルシート
    - `/api`
        - `client.js`: AJAXリクエストのクライアントで、GETとPOSTリクエストを発行可能
        - `server.js`: アプリがデータ取得時にアクセスする、ダミーのREST APIエンドポイント
    - `/exampleAddons`: 追加のReduxアドオン(addon)

## Todoアプリの要件定義

- 要件定義は、システム開発工程において、フェーズ①に該当
    - ①要件定義→②設計→③実装→④テスト→⑤リリース/保守

### Todoアプリのビジネス要件

- Todoアイテムリストを操作
- ユーザー入力を処理
- データ変更時にUIを更新

### Todoアプリに必要な機能

- アプリ最終ゴールのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/aca5aa56-0f38-184c-b674-7c5e1d426f54.png)

※ 引用元: [アプリ最終ゴールのイメージ](https://redux.js.org/tutorials/fundamentals/part-3-state-actions-reducers)

- UIは、3つのセクションで構成される
    - 新しいTodoアイテムを入力する入力ボックス
    - 既存のTodoアイテムのリスト
    - フッターセクション
        - 未完了Todoの数
        - フィルタリングオプション
- Todoアイテムに必要な機能
    - `完了`状態に切り替えるためのチェックボックス
    - カテゴリ別色分けされたタグ機能
    - Todoアイテム削除機能
- カウンターは、アクティブTodoの数を複数形にする必要あり
    - "0 items"/"1 item"/"3 items"
- 一括操作ボタン
    - すべてのTodoを完了としてマーク
    - 完了したすべてのTodoを削除
- タスクフィルタリングの方法
    - "All"/"Active"/"Completed"などアイテム状態に基づくフィルタリング
    - 選択しされたカラータグに基づくフィルタリング

### Stateの値を設計

- ReactとReduxのコア原則
    - UIは、stateに基づきレンダリングされる
- アプリ設計のアプローチ
    - 最初に、アプリ機能に必要なすべてのstateを考える
    - UIは、できるだけ少ないstateを使用し表現
        - 追跡/更新が必要なデータを少なくするため
- Todoアプリで考慮すべき2種類の状態
    - Todoアイテムのリスト
        - アプリの状態を表す
        - アプリの動作に必要なコアデータ
    - フィルタリングオプション
        - UIの状態を表す
        - アプリの今現在の実行状態を表す
- Todoアイテムごとに保存すべき情報
    - ユーザーが入力したテキスト
    - 完了したか否かを示すフラグ
    - 一意のID値
    - カラーカテゴリ(指定された場合)
- フィルタリングの種類を表す列挙値
    - 完了ステータス: "All", "Active", "Completed"
    - 色: "Red", "Yellow", "Green", "Blue", "Orange", "Purple"

### Stateの構造を設計

- stateは、プレーンなJavaScriptオブジェクトと配列に保持
    - stateに、以下のようなプレーンでないJSデータを使用できない
        - クラスを持たないインスタンス
        - 組み込みJSタイプ(Map/Set Promise/Dateなど)
        - 関数
- ルートのRedux stateは、通常プレーンなJSオブジェクト
    - その中に他のデータがネストされる
- Todoアプリで、stateに必要な値
    - Todoアイテムオブジェクトの配列
        - 各アイテムのフィールド
            - id: 一意の番号
            - text: ユーザーが入力したテキスト
            - completed: 完了したか否かを表すフラグ
            - color: カラーカテゴリ(オプショナル)
    - フィルタリングオプション
        - `完了`状態に基づくフィルタリング
        - 選択されたカラーカテゴリの配列によるフィルタリング
- Todoアプリで、stateの例
```
const todoAppState = {
  todos: [
    { id: 0, text: 'Learn React', completed: true },
    { id: 1, text: 'Learn Redux', completed: false, color: 'purple' },
    { id: 2, text: 'Build something fun!', completed: false, color: 'blue' }
  ],
  filters: {
    status: 'Active',
    colors: ['red', 'blue']
  }
}
```

- ※注意: Reduxの外にstateを持っても問題ない
    - 以下のようなstateは、Reduxに保持する必要なし
        - `このドロップダウンメニューは開いていますか?`
        - `フォーム入力の現在値`

## おわりに

Reduxを用いて、Todoアプリの要件定義と設計を行いました。
次回も続きます。お楽しみに。

##### [次回] [Django+Reactで学ぶプログラミング基礎(32): Reduxチュートリアル(Todoアプリの設計と実装)](https://qiita.com/mingchun_zhao/items/e83a812204966f6d4a83)