Todo App v3 (persistence)
In this demo, we build a yet more complex 'Todo' app, complete with persistence and a schema.
In the Todo App v1 (the basics) demo and the Todo App v2 (indexes) demo, refreshing the page reset all the todos, which didn't make it very useful. In this version, we demonstrate the basics of how to persist data from a Store
.
When data is persisted, it also valuable to have a schema for it, so in this demo we also add a simple schema for the todos.
We're making changes to the Todo App v2 (indexes) demo.
Additional Initialization
We will call the createLocalPersister
function to create a Persister
object that persists the the main Store
object in the browser's local store. Similarly, the createSessionPersister
function will create a Persister
object that persists the Store
object containing the user's current view:
<script src="/umd/tinybase/index.js"></script>
+<script src="/umd/tinybase/persisters/persister-browser/index.js"></script>
<script src="/umd/tinybase/ui-react/index.js"></script>
const {createIndexes, createStore} = TinyBase;
+const {createLocalPersister, createSessionPersister} = TinyBasePersisterBrowser;
const {
CellView,
Provider,
SliceView,
useAddRowCallback,
useCell,
useCreateIndexes,
+ useCreatePersister,
useCreateStore,
useSetCellCallback,
useSetValueCallback,
useValue,
} = TinyBaseUiReact;
Adding a TablesSchema
A Store
has a setTablesSchema
method which can be used to describe a schema of each Cell
present in each Table
. Here we will indicate that the text
Cell
and type
Cell
are strings, and we default the done
field to false
. The type
can only be one of the values of the TYPES
array:
const TYPES = ['Home', 'Work', 'Archived'];
+const SCHEMA = {
+ todos: {
+ text: {type: 'string'},
+ done: {type: 'boolean', default: false},
+ type: {type: 'string', default: 'Home', allow: TYPES},
+ },
+};
Persisting the Store
We create and memoize a Persister
object for the main Store
object. We'll start it auto-loading from the browser's local storage immediately, but we can also provide INITIAL_TODOS
as a default if nothing has been previously saved. We also set the Persister
object to auto-save, creating a continuous synchronization between the in-memory version of the Store
object and the copy of it in the browser's local storage.
Note that we don't set the initial data of the Store
object when we first create it, since it might have been persisted into the browser's local storage from a previous session, and we want to pick it up with the first load. We do configure the schema on creation though:
- const store = useCreateStore(() => createStore().setTables(INITIAL_TODOS));
+ const store = useCreateStore(() => createStore().setTablesSchema(SCHEMA));
+ useCreatePersister(
+ store,
+ (store) => createLocalPersister(store, 'todos/store'),
+ [],
+ async (persister) => {
+ await persister.startAutoLoad([INITIAL_TODOS]);
+ await persister.startAutoSave();
+ },
+ );
We do something similar for the viewStore
, so that reloads preserve the type currently being viewed. Instead of local storage, we'll use the browser's session storage. This means that if the user has two browser windows open, the UI changes to one won't mysteriously affect the other:
- const viewStore = useCreateStore(() =>
- createStore().setValue('type', 'Home'),
- );
+ const viewStore = useCreateStore(() =>
+ createStore().setValuesSchema({type: {type: 'string', default: 'Home'}}),
+ );
+ useCreatePersister(
+ viewStore,
+ (store) => createSessionPersister(store, 'todos/viewStore'),
+ [],
+ async (persister) => {
+ await persister.startAutoLoad();
+ await persister.startAutoSave();
+ },
+ );
Make some changes to the todos and then reload your browser!
We now have a fairly useful app for tracking todos and persisting the state. Please continue to the Todo App v4 (metrics) demo.