[Flutter/Dart]新規アイテム追加時のidの取得について
課題
前提
複数のアイテムを登録、保存
アイテムには一意なidをつけて管理
状態管理はredux 新規アイテム追加のフローは以下のようになります
viewでユーザからの入力を引数にAddItemActionを発行
reducerでstoreに{id, アイテム}を登録
middlewareでリモートデータベースに{id, アイテム}を登録

課題
新規アイテム追加時にidをどこで採番するか 上記フローによれば、採番する場所の候補としてはview、reducer、middlewareの3箇所があります。
解決方法
middlewareで採番するのが良いと考えます。
viewで採番する場合、以下の問題があります。
複数の異なるページやUIからアイテム追加する場合、処理が重複する
そもそもidはアプリ内の状態管理に関する変数で、viewが知るべきではない(関心事の分離)
reducerで採番する場合、以下の問題があります。
middlewareが新規idを知ることができない
詳細
と言うことで、middlewareで追加する具体的な方法を以下で述べていきます。
一番の課題は、middlewareで採番したidをどうやってreducerに伝えるか、と言うことです。
これには、以下のように対処します。
AddItemAction(Item)とAddItemWithIdAction(Item, int)を定義
viewは、ユーザの入力を元にAddItemActionを発行
middlewareは、AddItemActionを検知すると、新規idを採番し、AddItemWithIdActionを発行
reducerは、AddItemActionに対しては何もしない。AddItemWithIdActionを検知すると、引数のidとitemをstoreに追加

コードは以下のようになります。
//Actionの定義
class AddItemAction{
final Item item;
AddItemAction(this.item);
}
class AddItemWithIdAction{
final Item item;
final int id;
AddItemWithIdAction({required this.id, required this.item});
}
//middlewareの定義
void AppStateMiddleWare(Store<AppState> store, dynamic action,
NextDispatcher next) async {
if(action is AddItemAction){
int id = getId(); //新規idを採番
store.dispatch(
AddItemWithIdAction(id: id, item: action.item)
);
}
next(action);
if (action is AddItemWithIdAction){
saveToDB(action.id, action.item); //データベースに保存
}
}
AppState appStateReducer(AppState state, action){
if (action is AddItemWithIdAction){
return addItem(action.id, action.item, state);
//storeに{id, item}のペアを保存
}
return state;
}
最後に
やっぱりフレームワークに従おうとすると色々制約は出ますね。
最新記事
すべて表示現象 あるアイコンは長押し時に所定の動作を実行します これを実現するために、GestureDetectorのonLongPressに処理を登録していました しかしいざビルドしてみると、アイコンが表示されたタイミングで処理が実行されてしまいました 以下が該当部分のソースコードです。 さあ、どこが間違っているでしょう? return GestureDetector( child: Containe
前提 以下のようなケースを考えます。 アイテムの一覧がある ある1つのアイテムの詳細を表示するページがある 詳細ページではそのアイテムの削除ができる 削除したら他のページ(一覧ページなど)に戻る これはアプリではよくあるパターンだと思います。 課題 reduxパターンを用いている、より具体的にはProviderで状態を管理している場合、以下のような構成になっているのではないでしょうか? アプリ全体