SHIOPON LABO

しおぽん(@shiopon01)の個人ブログ

React/Reduxのスターターキットを公開している(2018/8/8更新)

React/Reduxビギナーのための、React/Reduxスターターキットを公開しているという記事。当初は最小限の機能で1ページのReduxアプリを作成するためのスターターキットを目指していたのだが、現在のSPA需用もありルーティングなどを追加した。

github.com

中身としては単純に、 react-create-app コマンドで作成したReactアプリにReduxを組み込んだ形。 package.json を見ると、追加したパッケージは基本的なReact/Redux関連のパッケージとコード整形系。webpackなど多くの部分は react-scripts に依存している。

  • react: "^16.4.2"
  • react-dom: "^16.4.2"
  • react-redux: "^5.0.7"
  • react-router-dom: "^4.3.1"
  • react-scripts: "1.1.4"
  • redux: "^4.0.0"
  • redux-logger: "^3.0.6"
  • redux-thunk: "^2.3.0"
  • eslint: "^5.2.0"
  • eslint-config-prettier: "^2.9.0"
  • eslint-plugin-import: "^2.13.0"
  • eslint-plugin-prettier: "^2.6.2"
  • eslint-plugin-react: "^7.10.0"
  • eslint-plugin-react-redux: "^2.3.0"
  • prettier: "^1.14.0"

Example: Todo List - Redux

ディレクトリ構造

ActionやReducerは専用のディレクトリやファイルに分けるのではなく、依存し合うそれぞれを1つのモジュール単位として、1つのファイルで管理する手法を採用している (Ducks proposalと呼ばれてる?) 。これを採用するため、ducks-modular-reduxを参考にした。

github.com

.
├── public                             # 静的ファイル
├── src                                # アプリのソースコード
│   ├── index.js                       # main render
│   ├── reducers.js                    # combine Reducers
│   ├── registerServiceWorker.js       # Offline cache https://goo.gl/KwvDNy
│   ├── shareComponents                # share Components
│   │   └── Header.js                  # page header
│   ├── utils                          # convenient things
│   │   ├── logo.svg                   # React icon
│   │   ├── consts.js                  # your ENV
│   │   └── injectStyle.js             # you can use `@keyframes`
│   └── app                            # application main sources
│        ├── App.js                    # application routing
│        ├── home                      # [home] `localhost:3000/`
│        │   ├── index.js              # [home] main Container
│        │   └── Home.js               # [home] main Component
│        └── todo                      # [todo] `localhost:3000/todo`
│             ├── index.js             # [todo] main Container
│             ├── Home.js              # [todo] main Component
│             ├── components           # [todo] Components
│             ├── containers           # [todo] Container Components
│             └── modules              # [todo] main action logic files (include in `Action`, `Reducer`, `Action Creator`)
│                  ├── reducers.js     # [todo] combine Reducers
│                  ├── todos.js        # [todo] todo module
│                  └── todos.spec.js   # [todo] todo module unit test
└── LICENSE                            # License is MIT

ducks-modular-reduxでは、依存するそれぞれのAction, Reducer, Action Creatorを1つのモジュールとして1つのファイルにまとめる手法を提案している。
よくある、ActionやReducerをそれぞれ専用のディレクトリやファイルとして/reducer/index.js/action.jsで管理されるパターンは、機能 (Action, Reducer) の追加が非常に煩わしい。たしかにうまく管理はできるのだが、実際にプログラミングしてアプリを作る場合、この面倒くささは未経験の想像する面倒くささを凌駕する。

このプロジェクトで採用しているプロジェクト構造は、全ての機能はモジュール単位で分けているため幾分マシだ。機能を追加したい場合、必要な分モジュールを追加するだけで良い。機能が大きくなると1ファイルが大きくなってしまうデメリットはあるが、可読性が失われることはほとんどないし、ファイル移動が必要ないというメリットがある。

// Actions
const LOAD   = 'my-app/widgets/LOAD';

// Reducer
export default function reducer(state = {}, action = {}) {
  switch (action.type) {
    default: return state;
  }
}

// Action Creators
export function loadWidgets() {
  return { type: LOAD };
}