永続化したデータを読み出す
いよいよ最後の工程です。永続化したデータを画面に表示しましょう。まずは、メモ作成画面から戻ってきたイベントで実行される処理を定義しましょう。MainScreenにリスト7のようなuseEffectフックを定義します。
const navigation = useNavigation();
useEffect(() => {
// (2)
const initialize = async () => {
// ここに表示更新処理を書く
};
const unsubscribe = navigation.addListener('focus', initialize); // (1)
return unsubscribe;
}, [navigation]);
(1)で利用しているnavigation.addListener()は、React Navigationの画面遷移イベントに応じて、任意の関数を呼び出すための仕組みです。第一引数に「画面が開かれたとき」を表すfocusを指定しているため、リスト6で実装したgoBack()で戻ってきたときに、第二引数の表示更新関数が実行されます。
メモリリークを避けるために、戻り値として購読停止(unsubscribe)用の関数が提供されているので、useEffectの戻り値(クリーンアップ関数)として登録しておくとよいでしょう。あとは(2)のinitialize関数を起点にして、保存されたデータを画面に表示する処理を呼び出すだけです。
データ取り出し、関数を永続化モジュールに実装して組み込む
それでは、永続化モジュールにデータを取り出す機能を追加していきましょう。今回は常に全データを取り出す仕様で作ります(リスト8)。
export const loadAll = async () => {
const keys = await AsyncStorage.getAllKeys(); // (1)
keys.sort(); // (2)
const entryList = await AsyncStorage.multiGet(keys); // (3)
return entryList.map(entry => JSON.parse(entry[1])); // (4)
};
Key-Valueストアで全データを取り出すためには、すべてのキーが必要です。そのため、まずこの処理では(1)のようにgetAllKeys()を使って、すべてのキーを取り出しています。リスト5で実装した通り、これらのキーはUNIXタイムの時刻を文字列化したものなので、(2)のようにソートすると時系列順になります。これらのキーを使って、全データを取り出しているのが(3)です。multiGet()関数は複数のキーを受け取って、それぞれに対応するデータを返却します。
ただ、このデータは[key, value][]という2次元配列になっており、使い勝手が悪いため、(4)で加工して、サンプルデータと同様のデータ型になおしています。では次に、このloadAll関数をMainScreenに実装してみましょう(リスト9)。
const navigation = useNavigation();
+ const [memos, setMemos] = useState([]); // (1)
useEffect(() => {
const initialize = async () => {
+ const newMemos = await loadAll(); // (2)
+ setMemos(newMemos);
};
const unsubscribe = navigation.addListener('focus', initialize);
return unsubscribe;
}, [navigation]);
画面に表示するデータを保持するために、(1)でuseStateを定義しました。サンプルデータの代わりに使うものなので、変数名はmemosにしてあります。これを定義した時点で、サンプルデータは削除しておきましょう。あとは、(2)でリスト8のloadAll関数を実行して、setMemosに保存すれば、useStateを通じてUIに反映されます。これで、自作のデータが画面に反映されるようになりました(図5)。
useEffectで取ってきたデータをuseStateに流し込んで画面を更新する手法は、React Hooksの常とう手段なので、覚えておくとよいでしょう。
まとめ
前回と今回の2回に分けて、アプリを1本作ってみました。今回作ったのは簡素なものでしたが、世の中のアプリの多くは「画面遷移」と「永続化データの保存・表示」を組み合わせて作られています。これらの知識を応用して、自分用のアプリを作り上げてみるのも面白いでしょう。
さて、このアプリを作る中でも、少し複雑なデータ構造が現れて、処理が想像しづらい部分もあったと思います。次回は、JavaScriptの拡張であるTypeScriptを用いて、データ構造を見やすくしていきます。
