データを永続化する
さて、画面ができたので、あとはデータを保存・読み出しする機能を組み込めば、アプリとして動くようになります。ただ、保存先についてはよく考える必要があります。
useStateを使えば、データを保持することができます。しかしこれは、メモリ内に一時的に保持しているだけなので、アプリを再起動すると失われてしまいます。再起動しても失われない、データを永続化する仕組みが必要なのです。React Nativeでデータを永続化するアプローチは、いくつかあります。主なものは次の3つです。
- 通信を行い、データをサーバーに保存する
- ローカル領域の簡易ストレージ(AsyncStorage)に保存する
- SQLiteなどのアプリ内データベースに保存する
サーバーを用意するのも大変な上、SQLiteでテーブルを作成するのも手間なため、今回はローカル領域にデータを保存することにしましょう。
ローカル領域の簡易ストレージ
アプリ内に簡単な設定情報などを保存する目的で、React NativeにはAsyncStorageというモジュールが用意されています。いわゆるKey-Valueストアで、キーとなる文字列と値となる文字列の組み合わせでデータを保存できます。以前はReact Nativeに内蔵されていましたが、現在は@react-native-community/async-storageの名称で、コミュニティによるメンテナンスが行われています。
ただ、@react-native-community/async-storageを利用できるのは、React Native CLIでプロジェクト管理を行っている場合のみです。本連載では、Expo CLIを用いてプロジェクト管理を行っているため、@react-native-community/async-storageを利用できません。Expoを利用している場合は、従来通りReact Nativeに内蔵されているAsyncStorageを利用します。
データ永続化モジュールを組み込む
それでは、実際にデータを保存するためのモジュールを作成しましょう。store.jsというファイルを作成し、AsyncStorageでデータ永続化を行う機能をこちらに集約します。まずは、テキストと作成日時を受け取って保存する、save関数を作りましょう(リスト5)。
import { AsyncStorage } from 'react-native';
export const save = async (text, createdAt) => {
const key = `${createdAt}`; // (2)
// (3)
const value = JSON.stringify({
text,
createdAt,
});
await AsyncStorage.setItem(key, value); // (1)
};
AsyncStorageにデータを保存するときには、(1)のようにsetItemを利用します。前述の通り、文字列でキーと値を登録するインターフェースです。Promiseを返すため、登録の完了を待ってから次の動作に移りたい場合には、async/awaitなどを使うとよいでしょう。キーには(2)のように、作成日時を文字列に変換して登録しました。奇妙に見えるかもしれませんが、後ほどデータを全件取り出すときに活躍します。値となる(3)は、MainScreenに配置したサンプルデータと同じデータ構造をJSON文字列で作成し、保存することにしました。
次に、これをメモ作成画面に組み込みます。リスト4で実装しておいた、保存ボタンのコールバック関数に追記していきます(リスト6)。
// 省略
import { TextInput, Button } from 'react-native-paper';
+ import { useNavigation } from '@react-navigation/native';
+ import { save } from './store';
export const ComposeScreen = () => {
const [ text, setText ] = useState('');
+ const navigation = useNavigation();
- const onPressSave = () => {
+ const onPressSave = async () => {
+ await save(text, Date.now()); // (1)
+ navigation.goBack(); // (2)
};
// 省略
(1)では、すでにuseStateで管理していたtextと現在時刻を組み合わせて、リスト5で用意したsave()関数に保存しています。その終了をawaitで待ってから、(2)のgoBack()関数で前の画面(=MainScreen)に戻る処理になっています。これで、メモ作成画面は完成しました。
