[Flutter]Reduxでsharedpreferenceからデータを読み込む
概要
flutterでスマホアプリを作っている。状態管理にはReduxを使用。アプリを切っても保持したいデータはsharedpreferenceに保存する。前回書き込みについて書いたので、今回は読み出しについてまとめる。
やり方
1. 保存する状態
以下のクラスを保存する。
class Item{
String name;
int id;
}
class AppState{
List<Item> items;
}
2. 各classにjsonから読み込むコンストラクタを作成
Item.fromJson(Map json){
id=json['id'] as int;
name=json['name'];
}
AppState.fromJson(Map json){
items=(json['items'] as List).map((m)=> Item.fromJson(m)).toList()
}
書き込みの場合と同様メンバにクラスインスタンスが含まれる場合は、そのクラスにもfromJson()コンストラクタを用意しておけば良い。
3. sharedpreferenceから読み出すメソッドを追加
Future<AppState> loadFromPrefs() async{
SharedPreferences prefs=await SharedPreferences.getInstance();
var string=prefs.getString('itemState');
if (string!=null){
Map map=json.decode(string);
return AppState.fromJson(map);
}
return AppState.InitState();
}
非同期にデータを読み込み、awaitで終了を待機する。
4. actionを追加
sharedpreferenceからstoreにデータを読み込むLoadItemActionと、storeからデータを読み出すGetItemActionを追加する。
class LoadItemAction{
final List<Item> items;
LoadItemAction(this.items);
}
class GetItemAction{}
LoadItemActionでは、storeに保存するためにsharedpreferenceから持ってきたデータを引数として持たせる。GetItemActionはstoreのデータを取り出すだけなので引数はなし。
5. reducerを追加
List<Item> ItemsReducer(List<Item> items, action){
//略
if (action is GetItemAction){
return items;
}
if (action is LoadItemAction){
return action.items;
}
}
LoadItemActionでは引数として渡されたデータを返し、GetItemActionではstoreから取り出したデータをそのまま返す。
6. middlewareを追加
sharedpreferenceから読み出すメソッドはmiddlewareに追加する。
void AppStateMiddleWare(Store<AppState> store, action, NextDispatcher next) async{
if (action is GetItemAction){
await loadFromPrefs()
.then((state) =>
store.dispatch(LoadItemAction(state.items)));
}
next(action);
}
sharedpreferenceからの読み込みをawaitで待って、完了したらLoadItemActionの引数に渡してstoreに保存。その後、GetItemAction(next(action))でstoreから呼び出される。
終わりに
注意したいのは、このsharedpreferenceから読み出すメソッドは非同期メソッドであるということ。データの読み出しが終わる前に本スレッドの方の動作が進まないよう注意する(もしくは進んでもいいように設計する)。(また別記事で書きたい)
最新記事
すべて表示やりたいこと TextFieldで入力フォームを作りたい。 例えば入力内容が金額の場合、3桁区切りで頭に¥を付けた表記にしたい。 ただしユーザにこれらを入力させるのではなく、ユーザはあくまで数字を入力するだけで、アプリ側で自動でフォーマットしたい。 方法...
現象 やってること iosシミュレータで画像をデバイスのローカルに保存 保存したパスをデータベースに保存 アプリ立ち上げ時にデータベースから画像パスを取得し、そのパスの画像を画面上に表示 起きている現象 iosシミュレータを再起動した場合、上記3で「ファイルパスが見つからな...
やりたいこと 初期値さえ決まればあとは不変な変数がある ただし、コンストラクタ起動時にはまだ決定できない このような変数について late finalで変数を定義 (何らかのタイミングで)初期化されたかどうかをチェックし、されていなければ値を入れる(チェックしないとfina...
Comments