useCreatePersister
The useCreatePersister
hook is used to create a Persister
within a React application along with convenient memoization and callbacks.
useCreatePersister<Persist, PersisterOrUndefined>(
store: undefined | PersistedStore<Persist>,
create: (store: PersistedStore<Persist>) => PersisterOrUndefined | Promise<PersisterOrUndefined>,
createDeps?: DependencyList,
then?: (persister: Persister<Persist>) => Promise<void>,
thenDeps?: DependencyList,
destroy?: (persister: Persister<Persist>) => void,
destroyDeps?: DependencyList,
): PersisterOrUndefined
Type | Description | |
---|---|---|
store | undefined | PersistedStore<Persist> | A reference to the |
create | (store: PersistedStore<Persist>) => PersisterOrUndefined | Promise<PersisterOrUndefined> | A (possibly asynchronous) function for performing the creation steps of the |
createDeps? | DependencyList | An optional array of dependencies for the |
then? | (persister: Persister<Persist>) => Promise<void> | An optional callback for performing asynchronous post-creation steps on the |
thenDeps? | DependencyList | An optional array of dependencies for the |
destroy? | (persister: Persister<Persist>) => void | An optional callback whenever the |
destroyDeps? | DependencyList | An optional array of dependencies for the |
returns | PersisterOrUndefined | A reference to the |
It is possible to create a Persister
outside of the React app with the regular createPersister function and pass it in, but you may prefer to create it within the app, perhaps inside the top-level component. To prevent a new Persister
being created every time the app renders or re-renders, since v5.0 the this hook performs the creation in an effect.
If your create
function (the second parameter to the hook) contains dependencies, the changing of which should cause the Persister
to be recreated, you can provide them in an array in the third parameter, just as you would for any React hook with dependencies. The Store
passed in as the first parameter of this hook is used as a dependency by default.
A second callback, called then
, can be provided as the fourth parameter. This is called after the creation, and, importantly, can be asynchronous, so that you can configure the Persister
with the startAutoLoad
method and startAutoSave
method, for example. If this callback contains dependencies, the changing of which should cause the Persister
to be reconfigured, you can provide them in an array in the fifth parameter. The Persister
itself is used as a dependency by default.
See the note below about possible future deprecation of the then
callback, however.
Since v4.3.0, the create
function can return undefined, meaning that you can enable or disable persistence conditionally within this hook. This is useful for applications which might turn on or off their cloud persistence or collaboration features. This hook can return undefined
if the Store
is not yet defined, which you should defend against.
Since v4.3.19, a destroy
function can be provided which will be called after an old Persister
is destroyed due to a change in the createDeps
dependencies that causes a new one to be created. Use this to clean up any underlying storage objects that you set up during the then
function, for example. If this callback itself contains additional dependencies, you can provide them in an array in the seventh parameter.
Since v5.2, the create
function can be asynchronous, which now makes it a suitable place to call the Persister
's startAutoLoad and startAutoSave
methods. At some major version in the future, the then
parameter will be removed, since that only really existed to perform such asynchronous initial tasks.
This hook ensures the Persister
object is destroyed whenever a new one is created or the component is unmounted.
Examples
This example creates a Persister
at the top level of a React application. Even though the App component is rendered twice, the Persister
creation only occurs once by default.
import {
useCreatePersister,
useCreateStore,
useTables,
} from 'tinybase/ui-react';
import React from 'react';
import {createRoot} from 'react-dom/client';
import {createSessionPersister} from 'tinybase/persisters/persister-browser';
import {createStore} from 'tinybase';
const App = () => {
const store = useCreateStore(createStore);
useCreatePersister(
store,
(store) => {
console.log('Persister created');
return createSessionPersister(store, 'pets');
},
[],
async (persister) => {
await persister.startAutoLoad();
await persister.startAutoSave();
},
);
return <span>{JSON.stringify(useTables(store))}</span>;
};
sessionStorage.setItem(
'pets',
'[{"pets":{"fido":{"species":"dog"}}}, {}]',
);
const app = document.createElement('div');
const root = createRoot(app);
root.render(<App />);
// -> 'Persister created'
// ...
root.render(<App />);
// No second Persister creation
console.log(app.innerHTML);
// -> '<span>{\"pets\":{\"fido\":{\"species\":\"dog\"}}}</span>'
root.unmount();
This example creates a Persister
at the top level of a React application. The App component is rendered twice, each with a different top-level prop. The useCreatePersister
hook takes the sessionKey
prop as a dependency, and so the Persister
object is created again on the second render. The first is destroyed and the destroy
parameter is called for it.
import {
useCreatePersister,
useCreateStore,
useTables,
} from 'tinybase/ui-react';
import React from 'react';
import {createRoot} from 'react-dom/client';
import {createSessionPersister} from 'tinybase/persisters/persister-browser';
import {createStore} from 'tinybase';
const App = ({sessionKey}) => {
const store = useCreateStore(createStore);
useCreatePersister(
store,
(store) => {
console.log(`Persister created for session key ${sessionKey}`);
return createSessionPersister(store, sessionKey);
},
[sessionKey],
async (persister) => {
await persister.startAutoLoad();
},
[],
(persister) =>
console.log(
`Persister destroyed for session key ${persister.getStorageName()}`,
),
);
return <span>{JSON.stringify(useTables(store))}</span>;
};
sessionStorage.setItem(
'fidoStore',
'[{"pets":{"fido":{"species":"dog"}}}, {}]',
);
sessionStorage.setItem(
'cujoStore',
'[{"pets":{"cujo":{"species":"dog"}}}, {}]',
);
const app = document.createElement('div');
const root = createRoot(app);
root.render(<App sessionKey="fidoStore" />);
// -> 'Persister created for session key fidoStore'
// ...
console.log(app.innerHTML);
// -> '<span>{\"pets\":{\"fido\":{\"species\":\"dog\"}}}</span>'
root.render(<App sessionKey="cujoStore" />);
// -> 'Persister created for session key cujoStore'
// -> 'Persister destroyed for session key fidoStore'
// ...
console.log(app.innerHTML);
// -> '<span>{\"pets\":{\"cujo\":{\"species\":\"dog\"}}}</span>'
root.unmount();
// -> 'Persister destroyed for session key cujoStore'
Since
v1.0.0