[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;
}
最後に
やっぱりフレームワークに従おうとすると色々制約は出ますね。
最新記事
すべて表示やりたいこと 2次元配列に作用する処理がある 処理の対象となる配列が複数ある このような場合、この処理は関数化したいが、引数をどう定義するのかちょっと迷った やり方 配列サイズは固定とすれば、以下のようにすればよい // Define a typedef for the...
やりたいこと 掲題の通りだが、関数ポインタの配列を定義したい。 具体的にどう使うかというと、例えばpthread_createの第3引数は新規スレッドで実行したい関数のポインタを渡す。複数の関数に対してそれぞれ新規スレッドを割り当てる場合、それらのポインタを配列にしてまとめ...
現象 配列がある インデックスを表す変数が配列のサイズ内かをチェックし、サイズ内の場合のみ要素にアクセス というよくあることをやろうとした val array = Seq.fill(ARRAY_SIZE)(...) when(i.U < ARRAY_SIZE){...
Comments