- Notifications
You must be signed in to change notification settings - Fork16
React Loads is a backend agnostic library to help with external data fetching & caching in your UI components.
License
jxom/react-loads
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
React Loads is a backend agnostic library to help with external data fetching & caching in your UI components.
- Hooks andRender Props to manage your async states & response data
- Backend agnostic. Use React Loads with REST, GraphQL, or Web SDKs
- Renderer agnostic. Use React Loads with React DOM, React Native, React VR, etc
- Automated caching & revalidation to maximise user experience between page transitions
- React Suspense support
- SSR support
- Preloading support
- Polling support to load data every x seconds
- Request deduping to minimise over-fetching of your data
- Focus revalidation to re-fetch your data when the browser window is focused
- Resources to allow your to hoist common async functions for built-in caching & reusability
- Finite set of state variables to avoid cryptic ternaries and impossible states
- External cache support
- Optimistic responses
- Pretty small –5kB gzipped
yarn add react-loadsor npm:
npm install react-loadsimportReactfrom'react';import*asLoadsfrom'react-loads';asyncfunctionfetchRandomDog(){// Dog fetcher logic here!// You can use any type of backend here - REST, GraphQL, you name it!}exportdefaultfunctionRandomDog(){const{ response, error, isPending, isResolved, isRejected}=Loads.useLoads('randomDog',fetchRandomDog);return(<div>{isPending&&'Loading...'}{isResolved&&<imgsrc={response.imgSrc}/>}{isRejected&&`Oh no!${error.message}`}</div>)}
TheuseLoads function accepts three arguments: acontext key, anasync function, and aconfig object (not used in this example). Thecontext key will store the response of thefetchRandomDog function in the React Loads cache against the key. Theasync function is a function that returns a promise, and is used to fetch your data.
TheuseLoads function also returns a set of values:response,error, and a finite set of states (isIdle,isPending,isResolved,isRejected, and a few others). If yourasync function resolves, it will update theresponse &isResolved values. If it rejects, it will update theerror value.
IMPORTANT NOTE: You must provide useLoads with a memoized promise (via
React.useCallbackorbounded outside of your function component as seen in the above example), otherwise useLoads will be invoked on every render.If you are using
React.useCallback, thereact-hooksESLint Plugin is incredibly handy to ensure your hook dependencies are set up correctly.
If your codebase isn't quite hook ready yet, React Loads provides a Render Props interface which shares the same API as the hook:
importReactfrom'react';import{Loads}from'react-loads';asyncfunctionfetchRandomDog(){// Dog fetcher logic here!// You can use any type of backend here - REST, GraphQL, you name it!}classRandomDogextendsReact.Component{render(){return(<Loadscontext="randomDog"fn={fetchRandomDog}>{({ response, error, isPending, isResolved, isRejected})=>(<div>{isPending&&'Loading...'}{isResolved&&<imgsrc={response.imgSrc}/>}{isRejected&&`Oh no!${error.message}`}</div>)}</Loads>)}}
- Basic
- Top movies
- Resources
- Typescript
- Render-as-you-fetch
- Stories
There are two main hooks:useLoads &useDeferredLoads.
useLoadsis called on first render,useDeferredLoadsis called when you choose to invoke it (it's deferred until later).
Let's focus on theuseLoads hook for now, we will explainuseDeferredLoads in the next section.
TheuseLoads hook accepts 3 parameters:
- A"context key" in the form of astring.
- It will help us with identifying/storing data, deduping your requests & updating other
useLoad's sharing the same context - Think of it as the namespace for your data
- It will help us with identifying/storing data, deduping your requests & updating other
- An"async function" in the form of afunction that returns a promise
- This will be the function to resolve the data
- An optional"config" in the form of anobject
importReactfrom'react';import*asLoadsfrom'react-loads';asyncfunctionfetchRandomDog(){// Dog fetcher logic here!// You can use any type of backend here - REST, GraphQL, you name it!}exportdefaultfunctionRandomDog(){const{ response, error, load, isPending, isReloading, isResolved, isRejected}=Loads.useLoads('randomDog',fetchRandomDog);return(<div>{isPending&&'Loading...'}{isResolved&&(<div><imgsrc={response.imgSrc}/><buttononClick={load}disabled={isReloading}>Load another</button></div>)}{isRejected&&`Oh no!${error.message}`}</div>)}
TheuseLoads hook represents a finite state machine and returns a set of state variables:
isIdleif the async function hasn't been invoked yet (relevant foruseDeferredLoads)isPendingfor when the async function is loadingisReloadingfor when the async function is reloading (typically truthy when data already exists in the cache)isResolvedfor when the async function has resolvedisRejectedfor when the async function has errored
It also returns aresponse variable if your function resolves, and anerror variable if rejected.
If you want to reload your data,useLoads also returns aload variable, which you can invoke.
TheuseLoads hook returnssome other variables as well.
Sometimes you don't want your async function to be invoked straight away. This is where theuseDeferredLoads hook can be handy. It waits until you manually invoke it.
importReactfrom'react';import*asLoadsfrom'react-loads';asyncfunctionfetchRandomDog(){// Dog fetcher logic here!// You can use any type of backend here - REST, GraphQL, you name it!}exportdefaultfunctionRandomDog(){const{ response, error, load, isIdle, isPending, isReloading, isResolved, isRejected}=Loads.useDeferredLoads('randomDog',fetchRandomDog);return(<div>{isIdle&&<buttononClick={load}>Load a dog</button>}{isPending&&'Loading...'}{isResolved&&(<div><imgsrc={response.imgSrc}/><buttononClick={load}disabled={isReloading}>Load another</button></div>)}{isRejected&&`Oh no!${error.message}`}</div>)}
In the above example, the dog image is fetched via theload variable returned fromuseDeferredLoads.
There are also some cases where including acontext key may not make sense. You can omit it if you want like so:
const{ ...}=useDeferredLoads(fetchRandomDog);
You can set configuration on either a global level, or a localuseLoads level.
By setting configuration on a global level, you are setting defaults for all instances ofuseLoads.
import*asLoadsfrom'react-loads';constconfig={dedupingInterval:1000,timeout:3000};exportdefaultfunctionApp(){return(<Loads.Providerconfig={config}> ...<Loads.Provider> )}
Warning: The
configprop must be memoized. Either memoize it usingReact.useMemoor put it outside of the function component.
See the full set of configuration options here
By setting configuration on auseLoads level, you are overriding any defaults set byLoads.Provider.
const{ ...}=useLoads('randomDog',fetchRandomDog,{dedupingInterval:1000,timeout:3000});
See the full set of configuration options here
If your async function needs some dependant variables (such as an ID or query parameters), use thevariables attribute in theuseLoads config:
asyncfunctionfetchDog(id){returnaxios.get(`https://dog.api/${id}`);}exportdefaultfunctionDogImage(props){const{ ...}=useLoads('dog',fetchDog,{variables:[props.id]});}
Thevariables attribute accepts an array of values. If your async function accepts more than one argument, you can pass through just as many values tovariables as the function accepts:
asyncfunctionfetchDog(id,foo,bar){// id = props.id// foo = { hello: 'world' }// bar = truereturnaxios.get(`https://dog.api/${id}`);}exportdefaultfunctionDogImage(props){const{ ...}=useLoads('dog',fetchDog,{variables:[props.id,{hello:'world'},true]});}
It may be tempting to not use thevariables attribute at all, and just use the dependencies outside the scope of the function itself. While this works, it will probably produce unexpected results as the cache looks up the record against thecontext key ('dog') and the set ofvariables. However, in this case, it will only look up the record against the'dog' context key meaning that every response will be stored against that key.
// DON'T DO THIS! IT WILL CAUSE UNEXPECTED RESULTS!exportdefaultfunctionDogImage(props){constid=props.id;constfetchDog=React.useCallback(()=>{returnaxios.get(`https://dog.api/${id}`);})const{ ...}=useLoads('dog',fetchDog);}
If you want to control whenuseLoads invokes it's async function via a variable, you can use thedefer attribute in the config.
exportdefaultfunctionRandomDog(props){// Don't fetch until shouldFetch is truthy.const{ ...}=useLoads('randomDog',fetchRandomDog,{defer:!props.shouldFetch});}
There may be a case where oneuseLoads depends on the data of anotheruseLoads, where you don't want subsequentuseLoads to invoke the async function until the firstuseLoads resolves.
If you pass a function tovariables and the function throws (due todog being undefined), then the async function will be deferred while it is undefined. As soon asdog is defined, then the async function will be invoked.
exportdefaultfunctionRandomDog(props){const{response:dog}=useLoads('randomDog',fetchRandomDog);const{response:friends}=useLoads('dogFriends',fetchDogFriends,{variables:()=>[dog.id]})}
Caching in React Loads comes for free with no initial configuration. React Loads uses the "stale while revalidate" strategy, meaning thatuseLoads will serve you with cached (stale) data, while it loads new data (revalidates) in the background, and then show the new data (and update the cache) to the user.
React Loads uses thecontext argument given touseLoads to store the data in-memory against a"cache key". Ifvariables are present, then React Loads will generate a hash and attach it to thecache key. In a nutshell,cache key = context + variables.
// The response of this will be stored against a "cache key" of `dog.1`const{ ...}=useLoads('dog',fetchDog,{variables:[1]});
React Loads will automatically revalidate whenever the cache key (context orvariables) changes.
// The fetchDog function will be fetched again if `props.context` or `props.id` changes.const{ ...}=useLoads(props.context,fetchDog,{variables:[props.id]});
You can change the caching behaviour by specifying acacheStrategy config option. By default, this is set to"context-and-variables", meaning that the cache key will be a combination of thecontext +variables.
// The response of this will be stored against a `dog` key, ignoring the variables.const{ ...}=useLoads('dog',fetchDog,{cacheStrategy:'context-only',variables:[props.id]});
By default, React Loads automatically revalidates data in the cache after5 minutes. That is, when theuseLoads is invoked and React Loads detects that the data is stale (hasn't been updated for 5 minutes), thenuseLoads will invoke the async function and update the cache with new data. You can change the revalidation time using therevalidateTime config option.
// Set it globally:import*asLoadsfrom'react-loads';constconfig={revalidateTime:600000}exportdefaultfunctionApp(){return(<Loads.Providerconfig={config}> ...</Loads.Provider>)}// Or, set it locally:exportdefaultfunctionRandomDog(){const{ ...}=useLoads('randomDog',fetchRandomDog,{revalidateTime:600000});}
React Loads doesn't set a cache expiration by default. If you would like to set one, you can use thecacheTime config option.
// Set it globally:import*asLoadsfrom'react-loads';constconfig={cacheTime:600000}exportdefaultfunctionApp(){return(<Loads.Providerconfig={config}> ...</Loads.Provider>)}// Or, set it locally:exportdefaultfunctionRandomDog(){const{ ...}=useLoads('randomDog',fetchRandomDog,{cacheTime:600000});}
On top of theisPending &isReloading states, there are substates calledisPendingSlow &isReloadingSlow. If the request is still pending after 5 seconds, then theisPendingSlow/isReloadingSlow states will become truthy, allowing you to indicate to the user that the request is loading slow.
exportdefaultfunctionRandomDog(){const{ isPending, isPendingSlow}=useLoads('randomDog',fetchRandomDog);return(<div>{isPending&&`Loading...${isPendingSlow&&'Taking a while...'}`}</div>)}
By default, the timeout is5 seconds, you can change this with thetimeout config option.
React Loads supports request polling (reload data everyx seconds) with thepollingInterval config option.
// Calls fetchRandomDog every 3 seconds.const{ ...}=useLoads('randomDog',fetchRandomDog,{pollingInterval:3000});
You can also add apollWhile config option if you wish to control the behaviour of when the polling should run.
// Calls fetchRandomDog every 3 seconds while `shouldPoll` is truthy.constshouldPoll=shouldTheDogBePollingRightNow();const{ ...}=useLoads('randomDog',fetchRandomDog,{pollingInterval:3000,pollWhile:shouldPoll});
You can also access therecord as the first parameter ofpollWhile if you provide a function.
// Calls processImage every 3 seconds while it's status is 'processing'.const{ ...}=useLoads('randomDog',fetchRandomDog,{pollingInterval:3000,pollWhile:record=>record?.response?.status==='processing'});
By default, all your requests are deduped on an interval of500 milliseconds. Meaning that if React Loads sees more than one request of the same cache key in under 500 milliseconds, it will not invoke the other requests. You can change the deduping interval with thededupingInterval config option.
To use React Loads with Suspense, you can set thesuspense config option totrue.
// Set it globally:import*asLoadsfrom'react-loads';constconfig={suspense:true}exportdefaultfunctionApp(){return(<Loads.Providerconfig={config}> ...</Loads.Provider>)}// Or, set it locally:exportdefaultfunctionRandomDog(){const{ ...}=useLoads('randomDog',fetchRandomDog,{suspense:true});}
Once enabled, you can use theReact.Suspense component to replicate theisPending state, and useerror boundaries to display error states.
functionRandomDog(){const{ response}=useLoads('randomDog',fetchRandomDog,{suspense:true});return<imgsrc={response.imgSrc}/>;}functionApp(){return(<React.Suspensefallback={<div>loading...</div>}><RandomDog/></React.Suspense>)}
React Loads has the ability to optimistically update your data while it is still waiting for a response (if you know what the response will potentially look like). Once a response is received, then the optimistically updated data will be replaced by the response.This article explains the gist of optimistic UIs pretty well.
ThesetResponse function is provided in ameta object as seen below.
importReactfrom'react';import*asLoadsfrom'react-loads';asyncfunctionfetchDog(id){// Fetch the dog}functionupdateDog(id,data){returnasyncmeta=>{meta.setResponse(data);// Fetch the dog}}exportdefaultfunctionRandomDog(props){constdogRecord=Loads.useLoads('dog',fetchDog,{variables:[props.id]});constupdateDogRecord=Loads.useDeferredLoads('dog',updateDog);return(<div>{dogRecord.isPending&&'Loading...'}{dogRecord.isResolved&&<imgsrc={dogRecord.response.imgSrc}/>}{dogRecord.isRejected&&`Oh no!${dogRecord.error.message}`}<buttononClick={()=>updateDogRecord.load(props.id,{imgSrc:'cooldog.png'})}> Update dog</button></div>)}
For async functions which may be used & invoked in many parts of your application, it may make sense to hoist and encapsulate them into resources.A resource consists of one (or more) async function as well as a context.
Below is an example of a resource and it's usage:
importReactfrom'react';import*asLoadsfrom'react-loads';// 1. Define your async function.asyncfunctiongetUsers(){constresponse=awaitfetch('/users');constusers=awaitresponse.json();returnusers;}// 2. Create your resource, and attach the loading function.constusersResource=Loads.createResource({context:'users',fn:getUsers});functionMyComponent(){// 3. Invoke the useLoads function in your resource.constgetUsersRecord=usersResource.useLoads();// 4. Use the record variables:constusers=getUsersRecord.response||[];return(<div>{getUsersRecord.isPending&&'loading...'}{getUsersRecord.isResolved&&(<ul>{users.map(user=>(<likey={user.id}>{user.name}</li>))}</ul>)}</div>)}
You can attach more than one loading function to a resource.But it's return value must be the same schema, as every response will update the cache.
You can also provide an array of 2 items to the resource creator (seen below withdelete); the first item being the async function, and the second being theconfig.
Here is an extended example using a resource with multiple async functions, split into two files (resources/users.js &index.js):
import*asLoadsfrom'react-loads';asyncfunctiongetUser(id){constresponse=awaitfetch(`/users/${id}`);constuser=awaitresponse.json();returnuser;}functionupdateUser(id,data){returnasyncmeta=>{awaitfetch(`/users/${id}`,{method:'post',body:JSON.stringify(data)});// `cachedRecord` is the record that's currently stored in the cache.constcurrentUser=meta.cachedRecord.response;constupdatedUser={ ...currentUser, ...data};returnupdatedUser;}}asyncfunctiondeleteUser(id){awaitfetch(`/users/${id}`,{method:'delete'});return;}exportdefaultLoads.createResource({context:'user',fn:getUser,// You can supply either a async function, or an array of async function/config pairs.update:[updateUser,{timeout:3000}],delete:deleteUser});
importReactfrom'react';importDeleteUserButtonfrom'./DeleteUserButton';importUpdateUserFormfrom'./UpdateUserForm';importusersResourcefrom'./resources/users';functionMyComponent(props){const{ userId}=props;constgetUserRecord=usersResource.useLoads({variables:[userId]});constuser=getUserRecord.response||{};constupdateUserRecord=usersResource.update.useDeferredLoads({variables:[userId]});constdeleteUserRecord=usersResource.delete.useDeferredLoads({variables:[userId]});return(<div>{getUserRecord.isPending&&'loading...'}{getUserRecord.isResolved&&(<div> Username:{user.name}<DeleteUserButtonisLoading={deleteUserRecord.isPending}onClick={deleteUserRecord.load}/><UpdateUserFormonSubmit={data=>updateUserRecord.load(userId,data)}/></div>)}</div>)}
If you would like the ability to persist response data upon unmounting the application (e.g. page refresh or closing window), a cache provider can also be utilised to cache response data.
Here is an example usingStore.js. You can either set the external cache provider on a global level or auseLoads level.
import*asLoadsfrom'react-loads';importstorefrom'store';constconfig={cacheProvider:{get:key=>store.get(key),set:(key,val)=>store.set(key,val),reset:()=>store.clearAll()}}exportdefaultfunctionApp(){return(<Loads.Providerconfig={config}> ...</Loads.Provider>)}
import*asLoadsfrom'react-loads';importstorefrom'store';constcacheProvider={get:key=>store.get(key),set:(key,val)=>store.set(key,val),reset:()=>store.clearAll()}exportdefaultfunctionRandomDog(){const{ ...}=Loads.useLoads('randomDog',fetchRandomDog,{ cacheProvider});}
React Loads comes with the ability to eagerly preload your data. You can do so using thepreload function.
constrandomDogLoader=Loads.preload('randomDog',fetchRandomDog);
Thepreload function shares the same arguments as theuseLoads function, however,preload is not a React Hook and shouldn't be called in your render function. Instead, use it inside event handlers, route preparation, or call it on first render.
Thepreload function will essentially fetch & cache your data in the background. It does not return any value apart from auseLoads hook. When theuseLoads hook is invoked, it will read the data from the cache that was previously loaded bypreload, and won't re-fetch your data. If no cached data exists, it will go ahead and fetch it.
constrandomDogLoader=Loads.preload('randomDog',fetchRandomDog);functionRandomDog(){const{ response}=randomDogLoader.useLoads({suspense:true});return<imgsrc={response.imgSrc}/>;}functionApp(){return(<React.Suspensefallback={<div>Loading...</div>}><RandomDog/></React.Suspense>)}
Thepreload function is designed to implement the"render-as-you-fetch" pattern. Ideally,preload can be invoked when preparing your routes, or inside an event handler, where you can then use theuseLoads function inside your component.
const{ response, error, load, isIdle, isPending, isPendingSlow, isReloading, isReloadingSlow, isResolved, isRejected, reset, state, isCached}=useLoads(context,fn,config);
context
string
A unique identifier for the request.
fn
function
A function that returns a promise to retrieve your data.
config
object| optional
A set ofconfiguration options
any
Response from the resolved promise (fn).
any
Error from the rejected promise (fn).
function
Trigger to invokefn.
boolean
Returnstrue if the state is idle (fn has not been invoked).
boolean
Returnstrue if the state is pending (fn is in a pending state).
boolean
Returnstrue if the state is pending for longer thantimeout milliseconds.
boolean
Returnstrue if the state is reloading (fn is in a pending state &fn has already been invoked or cached).
boolean
Returnstrue if the state is reloading for longer thantimeout milliseconds.
boolean
Returnstrue if the state is resolved (fn has been resolved).
boolean
Returnstrue if the state is rejected (fn has been rejected).
function
Function to reset the state & response back to an idle state.
string
State of the promise (fn).
boolean
Returnstrue if data exists in the cache.
const{ response, error, load, isIdle, isPending, isPendingSlow, isReloading, isReloadingSlow, isResolved, isRejected, reset, state, isCached, update}=useDeferredLoads(context,fn,config);// OR}=useDeferredLoads(fn,config);
context
string| optional
A unique identifier for the request. This is optional foruseDeferredLoads.
fn
function
A function that returns a promise to retrieve your data.
config
object| optional
A set ofconfiguration options
A hook which enables you to retrieve a record from the cache.
// Including `context` onlyconstrandomDogRecord=useCache('randomDog');// Including `context` & `variables`constdogRecord=useCache('dog',{variables:[0]});
The unique identifier of the record to retrieve.
An array of variables (parameters).
any
Response of the cached record.
any
Error of the cached record.
any
State of the cached record.
A hook which composes a set of records, and gives you a singular state.
Without usinguseGetStates, you may run into situations like this:
constrandomDogRecord=useLoads('randomDog',fetchRandomDog);constdogFriendsRecord=useLoads('dogFriends',fetchDogFriends);<div>{(randomDogRecord.isPending||dogFriendsRecord.isPending)&&'Loading...'}{randomDogRecord.isResolved&&dogFriendsRecord.isResolved&&'Loaded!'}</div>
But, if you compose your records insideuseGetStates, you can clean up your state variables:
constrandomDogRecord=useLoads('randomDog',fetchRandomDog);constdogFriendsLoader=useLoads('dogFriends',fetchDogFriends);const{ isPending, isResolved, isRejected}=useGetStates(randomDogRecord,dogFriendsRecord);
Set global configuration with the<Provider> component.
import*asLoadsfrom'react-loads';constconfig={cacheTime:600000}exportdefaultfunctionApp(){return(<Loads.Providerconfig={config}>{/* ... */}</Loads.Provider>)}
Object
An object ofconfiguration options
constresource=createResource(options);
string
The context of the resource. Used to generate a cache key.
function
A function that returns a promise to retrieve your data.
Any key you provide to the resource is an async function.
constdogsResource=createResource({context:'dogs',fn:getDogs,create:createDog,foo:getDogFoo,bar:getDogBar,baz:getDogBaz});// In your function component - will invoke the `bar` async function in createResource:dogsResource.bar.useLoads();
AuseLoads hook which can be invoked in your function component.
The arguments are a bit different to the standaloneuseLoads hook - it only optionally accepts aconfig object, and not acontext or an async function (fn).
resource.useLoads(config)
AuseLoads hook which can be invoked in your function component.
The arguments are a bit different to the standaloneuseDeferredLoads hook - it only optionally accepts aconfig object, and not acontext or an async function (fn).
resource.useDeferredLoads(config)
Same as thepreload function, however only accepts aconfig object as it's only parameter.
resource.preload(config)
constloader=preload(context,fn,config);
context
string| optional
A unique identifier for the request. This is optional foruseDeferredLoads.
fn
function
A function that returns a promise to retrieve your data.
config
object| optional
A set ofconfiguration options
useLoads
AuseLoads hook which can be invoked in your function component.
The arguments are a bit different to the standaloneuseLoads hook - it only optionally accepts aconfig object, and not acontext or an async function (fn).
loader.useLoads(config)
config={ cacheProvider, cacheStrategy, cacheTime, context, dedupingInterval, delay, defer, initialResponse, loadPolicy, onReject, onResolve, pollingInterval, pollWhenHidden, rejectRetryInterval, revalidateTime, revalidateOnWindowFocus, suspense, throwError, timeout, update, variables}
{ get: function(key), set: function(key, val), reset: function() }
Set a custom cache provider (e.g. local storage, session storate, etc). Seeexternal cache providers for an example.
string| Default:"context-and-variables"
The caching strategy for your loader to determine the cache key.
Available values:
"context-only"- Caches your data against the
contextkey only.
- Caches your data against the
"context-and-variables"- Caches your data against a combination of the
contextkey &variables.
- Caches your data against a combination of the
number| Default:0
Time (in milliseconds) that the data remains in the cache. After this time, the cached data will be removed.
number| Default:500
Interval (in milliseconds) that requests will be deduped in this time span.
number| Default:0
Time (in milliseconds) before the component transitions to the"pending" state upon invokingfn.
boolean
If set totrue, the async function (fn) won't be called automatically and will be deferred until later.
Ifdefer is set to true, the initial state will beidle.
any
Set initial data for the request. Useful for SSR.
string| Default:"cache-and-load"
A load policy allows you to specify whether or not you want your data to be resolved from the Loads cache and how it should load the data.
"cache-only":useLoadswill only return data from the cache. It will not invoke the async function."cache-first": If a value for the loader already exists in the Loads cache, thenuseLoadswill return the value that is in the cache, otherwise it will invoke the async function."cache-and-load": This is the default value and means thatuseLoadswill return with the cached value if found, but regardless of whether or not a value exists in the cache, it will always invoke the async function."load-only": This means thatuseLoadswill not return the cached data altogether, and will only return the data resolved from the async function.
function(error)
A hook that is invoked when the async function (fn) rejects.
function(response)
A hook that is invoked when the async function (fn) resolves.
number
If set, thenuseLoads will invoke the async function (fn) everyx amount of seconds.
boolean | function(record)
If set, thenuseLoads will poll while the condition is truthy.
boolean| Default:false
If truthy, thenuseLoads will continue to poll when the window is not focused.
number | function(count)
If set, anduseLoads rejects, thenuseLoads will continue to try and resolvefn everyx seconds. If a function is given, you can determine the interval time with that.
Example:
// Retry every 1000 milliseconds.rejectRetryInterval:1000// Retry every "error count" * "2000 milliseconds".rejectRetryInterval:count=>count*2000
number| Default:300000(5 minutes)
Time that the data in the cache remains "fresh". After this time, data in the cache will be marked as "stale", meaning that the data will have to be reloaded on next invocation.
boolean| Default:false
If truthy,useLoads will load the async function (fn), when the browser window is focused again.
boolean| Default:false
If truthy, this will enable React Suspense mode.
boolean| Default:false
If truthy and the async function (fn) rejects, thenuseLoads orload will throw the error.
number| Default:5000(5 seconds)
Number of milliseconds before the component transitions to theisPendingSlow orisReloadingSlow state. Set to0 to disable.
Note:useLoads will still continue to try and resolve while in theisPendingSlow state
Array<any>
An array of variables (parameters) to pass to your async function (fn).
- "I'm super excited about this package" -Michele Bertoli
- "Love the API! And that nested ternary-boolean example is a perfect example of how messy React code commonly gets without structuring a state machine." -David K. Piano
- "Using case statements with React components is comparable to getting punched directly in your eyeball by a giraffe. This is a huge step up." -Will Hackett
- "I used to get the shakes coding data fetch routines with React. Not anymore. Using react loads, I now achieve data fetching zen." -Claudia Nadalin
- "After seeinghttps://twitter.com/dan_abramov/status/1039584557702553601?lang=en, we knew we had to change our loading lifecycles; React Loads was our saviour." -Zhe Wang
- David K. Piano for state machine inspiration
- React Query &Zeit's SWR for design inspiration & ideas
MIT ©jxom
About
React Loads is a backend agnostic library to help with external data fetching & caching in your UI components.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors4
Uh oh!
There was an error while loading.Please reload this page.