injectPromise
import { injectPromise } from '@zedux/react'
An injector that creates a memoized promise reference. Returns an AtomApi with a promise and store attached. This AtomApi's store tracks the promise's state.
Accepts a promise factory function, a list of dependencies (similar to injectMemo()
and injectEffect()
), and an optional config object.
const atomApi = injectPromise(createPromise, [dep1, dep2], {
dataOnly,
initialState,
})
const { promise, store } = atomApi
injectPromise
calls the factory function immediately to produce the promise. It doesn't defer the side effect like injectEffect
would.
The state of the store returned by this injector is patterned after React Query's query state.
Example
The advantage of using injectPromise
over query atoms is that it gives you more control over when the promise is recreated.
It also gives you access to the promise and store so you can compose them with other promises/stores or handle/subscribe to them yourself.
Signature
- Simplified
- TypeScript
injectPromise = (promiseFactory, deps?, config?) => atomApi
declare const injectPromise: {
<T>(
promiseFactory: (controller?: AbortController) => Promise<T>,
deps: InjectorDeps,
config: Omit<InjectPromiseConfig, 'dataOnly'> & {
dataOnly: true
} & InjectStoreConfig
): AtomApi<{
Exports: Record<string, any>
Promise: Promise<T>
State: T
Store: Store<T>
}>
<T>(
promiseFactory: (controller?: AbortController) => Promise<T>,
deps?: InjectorDeps,
config?: InjectPromiseConfig<T> & InjectStoreConfig
): AtomApi<{
Exports: Record<string, any>
Promise: Promise<T>
State: PromiseState<T>
Store: Store<PromiseState<T>>
}>
}
Required. A function that returns a promise. Signature:
- Simplified
- TypeScript
promiseFactory = (controller) => promise
promiseFactory: (controller?: AbortController) => Promise<T>
An AbortController. Use this controller's signal to abort fetch requests or run your own cleanup.
Will be undefined
if AbortController is not available in the current environment.
injectPromise
's store to track.Optional. An array containing anything.
When any items in the array change on a subsequent evaluation, injectPromise()
will call the promise factory again and reset the state of the store for the new promise.
Pass an empty array if you want the promise to never be recreated. Pass undefined
to recreate the promise on every evaluation (not usually what you want).
Optional. An object with the following optional properties:
{ dataOnly, initialState, runOnInvalidate, ...storeConfig }
Optional. Boolean. Default false
.
If true, the store's state will only contain the promise's resolved value (aka "data"), instead of an object containing data
, isLoading
, etc properties.
const { store } = injectPromise(promiseFactory, [])
store.getState() // { ...status flags..., data: <the data> }
// with dataOnly:
const { store } = injectPromise(promiseFactory, [], { dataOnly: true })
store.getState() // <the data>
Optional. Should match the type of the promise's resolved value. Default undefined
.
The initial value of the store's data
property. If dataOnly
is true, this will be the entire state of the store.
Without this specified, the store's data
will be undefined
until the promise resolves
Optional. Boolean. Default false
.
If true, the promise factory will rerun when the current atom instance reevaluates due to an invalidate
call.
Essentially a shorthand for doing this yourself:
const reasons = injectWhy()
const counterRef = injectRef(0)
if (reasons.some(reason => reason.type === 'cache invalidated')) {
counterRef.current++
}
const promiseApi = injectPromise(myPromiseFactory, [counterRef.current])
Optional. Configuration properties for the created store.
These are passed directly on to injectStore()
. See available options here.
An AtomApi. This AtomApi's .promise
property is a reference to the promise returned from the promiseFactory
. This AtomApi's .store
property is a store with a PromiseState shape that tracks the state of the promise.
This AtomApi can be returned directly from the atom state factory. Or you can consume/compose the promise and store however you want.
const { promise, store } = injectPromise(...)