react-redux の設計指針
これは某所での設計を決める用の資料です
- フレームワーク
- React
- React/Redux (Recommended)
- Redux Middleware
- None
- redux-thunk
- redux-promise (Recommended)
- redux-saga
- redux-observable
- Redux Reducer
- Domain with Selector
- Domainless
- HMR
- On
- Off
- SSR
- On
- Off
- CSS
- Independent
- CSS Module
- CSS in JS
- styled-components
- Type System
- Babel/Flow
- TypeScript
- 一通り枯れたフェーズ
- フロントエンドの荒野の中で仮のレールに乗りたいならこれ
- 採用する middleware と、 reducer の設計指針で派閥がある
- 個人的な感想だと…
- React/Angularに対して後出しジャンケンしてるので便利な部分は便利
- React と同じ水準まで便利になることはあっても、Reactを超えることはないと思う
- 個人的な感想だと…
- 独自テンプレート、独自エコシステム、Rx界を許容するか
- 僕はあんまり好きじゃないです
コアはこれだけ
type reducer = (State, Action) => State
- 前の状態と、新しく流れてくる Action で、次の状態を決める
- 複数の reducer を合成して一つの関数にする(ことが多い)
- ビューに関与するデータだけ持つ派
- ドメイン層を直接知らない
- Presentational な Layer に徹する
- ドメインデータを大量に持つ派
- ドメイン層に近い振る舞いをする
- ビューに関与するデータ
- 画面ごとにその画面を抽象する reducer を置く
- RESTに応じてその結果をそのまま格納してそのまま表示する
- サーバー側のデータ構造と密に紐づく
- Twitter Mobile だと…
tweets[id] = {...}
という Map 構造に格納するtimeline = id[]
やmentions = id[]
という配列でリレーショナルな構造をとる
画面に表示する際は、ステートからさらに再計算してReactに渡す。 それらを selector と言ったりする。 そのヘルパが https://github.com/reactjs/reselect
- 要件/複雑度次第
- どっちが正しいとかはない
- 現実的な「Web」だと前者がフィットするし、デスクトップアプリだと後者に近づく
- Actionのストリームを別のストリームに変換する層
- 名前がよくない。 Action Mapper とかが適切では
- Middleware 不要派
- 必ず直接 reducer へ dispatch する
- ビューにロジック書かれがちなのが難点
- 用途ごとに middleware 書く派
- たとえば 特定のエンドポイントの api call を抽象する
- 無限に増えていくので実質↓と変わらない状態になりがち
- thunk派
- middleware api がむき出しで自由度が高すぎる
- redux の中の実装に踏み入りすぎてしまう
- promise派
- 素朴
- 1:1 の関係以外うまくかけない
- saga派
- ジェネレーターで状態を抱えながら複数回 dispatch
- アクションとreducerへのdispatchの 1:N や N:1 の関係をうまく書ける
- 状態を抱える奇形なRxだと思う
- Rx派 (redux-observable) - Angular と違って React界では主流ではない
- ビュー側から request-api-call を dispatch
- middleware が lock-ui を発行
- middleware が update-api-result を発行
- middleware が unlock-ui を発行
これで 1:3 の関係
- 不特定多数に公開するAPIのデータのペイロード削減に効果を発揮
- 逆に言えばそうでないケースはオーバーキル
- 真に必要なのは「複数のリクエストを合成する層」で、要は愚直なRESTのN+1問題を避けたい
- GraphQL持ち出さずとも、サービスごとに View API を提供すれば解決する問題
- 教条的なRESTに縛られると重大なパフォーマンス問題を抱えることが多い
- 結果としてBFFと切り口は同じ
- SEO を気にするなら残念ながら現状必須 (Google頑張って…)
- First Meaningful Paint を気にするならやる
- 「いずれやりたいね」程度でも最初からそういう設計にしないと後付は難しい
- そうでないなら余力がよっぽどない限りはやらない
- BFFを置けるなら next.js などで対応可能
- なかなかペイしづらい部分
- 後方互換の確認にスナップショットテストが有用
- やるならava/enzyme を推奨
- 純粋関数なので書きやすい、が…
- Reduxがドメインレスな場合、あんまり意味がない(サーバー側に実体があるため)
- pupetteer が便利そう
- ヘッドレスChromeなのでクロスブラウザテストは別途必要
- PRごとに連番スクショで目視チェックぐらいがペイする限界ではないか
- 何かと壊れるので維持が大変
- マークアッパーと JSer で前者の人数が多いならメリットが大きい
- 素早くコンポーネントをプレビューしたい、程度なら react-storybook などで十分な可能性がある
- 何かと壊れるのでry
- webpack での設定がヤバイ感じになるので、メンテ側としてはあまり入れたくないが…
- こだわりがないなら要件をマークアップする人の意見で決めるのがよい
- semantic-ui-react などで基本的なデザインを丸投げするという方法もなくはない
- (個人的に)破壊的変更を繰り返す mjackson が信用ならないが…
- v4 はいつまで大丈夫だろうか…
- 必要なら path-to-regexp で自分で書く
- 他も検討する
- 現代ではとりあえず必須でいいのでは
- Flowの方が導入は楽だし負荷は少ない
- TypeScriptは開発環境を揃えたり周辺ライブラリの型を整えれば強い
- 個人的には yarn
- npm5 が遅くて色々壊れててストレス
- monorepo も構成もアリ