のらねこの気まま暮らし

技術系だけど、Qiita向きではないポエムとかを書くめったに更新されないヤツ

React Native に Reduxを加え、ロジックを実装する

概要

React Native入門シリーズその3。 Reduxを導入してAPI通信してViewに引き渡す。

前回: ReactNativeにTypeScriptを導入する - のらねこの気まま暮らし

APIについて

OpenWeather

アプリについて

今回試すことが主軸にあって、 「こういうView」っていう提案まで考えてない。よって実用的ではないものだが、アプリの構成について考える土台として雑に作る。

インタラクション

本来なら、今の天気を取得しつつ予報も出すべきだが前述の通り手抜きで対応する。

  1. ボタンを押したら、天気の読み込みが始まる。
  2. 天気の読み込みが完了したら、天気の情報を表示する。

View設計

  • 今の天気を取得するボタン
  • 天気の状態をそのまま表示

アーキテクチャ

アプリの構造を考えるぞい。

選定

  • Redux Way
  • Redux Way Arrange
  • Ducks

Redux Way系は役割でコードを分ける、Ducksは関心でコードを分ける。

個人的にクライアントの関心はViewの側面から見たActionとアプリ全体から見たStateに分けられると思っていて、そこを密結合することに懸念がある(実際、Vuexでも結構悩んだ)。

今回はReduxについて真剣に考えるより、React Nativeを知ることが目的なので複雑な悩みを抱えたくない。

しかし、Redux Wayは僕の感覚に則さない...

ということで感覚的にしっくり来るようにRedux WayをArrangeする。

Redux Way Arrange

View層

React Componentを配置する。 Container,Presentational,AppRootを管理する。

UseCase層

Viewから入力を受け取り、dispatchのタイミングを制御する。 いざ名乗ってみると違和感しかない。 Containerと対応する。

Action層

ActionCreator。

UserCaseで構築したデータをActionにパッキングする。 ここはもっと隠蔽できると嬉しい。

究極、s2sとか使って自動生成したい。

Store層

Redux Storeの初期化と、Reducerの定義を担う。 Reducer基本的にStoreからしか参照されないしっていうかStoreの一部だよね、の気持ち。

ReducerはViewではなく、アプリ内のドメインと対応する。 Stateはアプリにおける情報のドメイン

Service層

名前に悩んだけどまあとりあえず。

外部APIとの通信、アプリへの最適化を担う。 だいたい外部APIを使う場合(それが自前で用意したAPIだとしても)要求以上の実装がされがちなので、そういう本質的ではないが必要なことをまとめておく場所。

基本的にUseCaseからしか呼ばれない。

実装フロー

事前想定:

  1. 天気取得ボタンの作成
  2. 天気取得のUseCaseの作成
  3. Reducerの雛形
  4. OpenWeather API取得の実装
  5. UserCase内でAPI呼び出し
  6. weather用のReducerを定義
  7. ViewにReducerから取得したデータを表示

実際:

  1. React + Reduxの雛形作成
  2. ボタンの作成
  3. 天気取得のUseCaseの作成
  4. Actionの作成
  5. Reducerの作成
  6. 型の定義(Action, State, Props, etc)
  7. Weather用のReducerを定義
  8. ここでContantsが必要だと判断
  9. OpenWeather API取得の実装
  10. weatherのReducerに実データとローディングフラグを実装
  11. Viewに読み込み時の処理と天気表示を実装

つまったところ

  • connectの実装と型定義
  • Object.assignの引数の順番間違えた
  • OpenWeather APIの仕様調査と型定義

モジュールの変化

core

  • react-redux
  • redux
  • @types/react-redux
  • @types/redux

service

  • axios
  • qs
  • @types/qs

所感

TypeScriptの警告つぶしが結構面倒だった。 Reducer定義しないといけないことを知った。 OpenWeatherAPIの仕様以外と知らなくて手間取った。 土台ができちゃえばあとは継ぎ足しで行けるかなって思った。 あれ、ReactNativeってなんだっけ?

github.com