@vlsergey/react-indexdb-cache
v0.13.1
Published
IndexedDb-backed cache for react application
Downloads
7
Maintainers
Readme
react-indexdb-cache
Flexible indexeddb-backed cache for react application
- Uses IndexedDb to store cached data, thus it can be used even if user reloads page or reopen browser window.
- Tries to reduce number of component render calls as much as possible. For example changing key order in arguments from
['first', 'second']
to['second', 'first']
will return sameRecord<string,...>
object instance. Thus it's safe to use cache result asuseMemo
orReact.memo
argument.
Usage
Cache definition
Create new file and define loader, cache instance and access helpers (hooks and components):
import {cacheValueProviderFactory, cacheValuesProviderFactory, CacheWithIndexedDb,
cacheValueHookFactory, cacheValuesHookFactory} from '@vlsergey/react-indexdb-cache';
type Key = string;
type Value = number;
async function loader(key : Key) : Promise<Value | undefined> {
// place actual key to value resolving here
return 42;
}
export const cache = new CacheWithIndexedDb<string, number, number>({
loader,
databaseName: 'testDatabase', // name of IndexedDb database name
});
export const CacheValueProvider = cacheValueProviderFactory(testCache, true);
export const CacheValuesProvider = cacheValuesProviderFactory(testCache);
export const useCacheValue = cacheValueHookFactory(propertiesDataCache);
export const useCacheValues = cacheValuesHookFactory(propertiesDataCache);
export default cache
It is advised to use batching function (like one from @vlsergey/batcher
) to group multiple async calls into batches.
import Batcher from '@vlsergey/batcher';
async function batchLoader(keys : Key[]) : Promise<(Value | undefined)[]> {
// place actual key to value resolving here
return keys.map( key => 42 );
}
const batcher = new Batcher<string, number>(batchLoader, {
maxBatchSize: 50
});
export const cache = new CacheWithIndexedDb<string, number, number>({
loader: key => batcher.queue(key),
databaseName: 'testDatabase', // name of IndexedDb database name
});
Cache usage
Use cache values in functional of class components.
import {CacheValueProvider, CacheValuesProvider, useCacheValue, useCacheValues} from "./myCache.ts"
interface MyComponentProps {
entityId?: string
}
function MyComponent({
entityId
} : MyComponentProps) => {
const valueFromCache : number | undefined = useCacheValue( entityId );
return valueFromCache ? <span>{valueFromCache}</span> : <span>Loading...</span>
}
interface MyComponentProps {
entityId?: string
}
function MyComponent({
entityId
} : MyComponentProps) => <CacheValueProvider cacheKey={entityId}>{ (valueFromCache : number | undefined) =>
valueFromCache ? <span>{valueFromCache}</span> : <span>Loading...</span>
}</CacheValueProvider>
interface MyComponentProps {
entityIds: readonly string[]
}
function MyComponent({
entityIds
} : MyComponentProps) => {
const valuesFromCache : Record<string, number> = useCacheValues( entityIds );
return JSON.stringify(valuesFromCache)
}
interface MyComponentProps {
entityIds: readonly string[]
}
function MyComponent({
entityIds
} : MyComponentProps) => <CacheValuesProvider cacheKeys={entityIds}>{ (valuesFromCache : Record<string, number>) =>
valueFromCache ? <span>{valueFromCache}</span> : <span>Loading...</span>
}</CacheValuesProvider>