- Notifications
You must be signed in to change notification settings - Fork30
Complex Loader Management Hook for React Applications
License
f/react-wait
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Complex Loader Management Hook forReact.
Read theMedium post "Managing Complex Waiting Experiences on Web UIs".
react-wait is aReact Hook helps to manage multiple loading states on the page without any conflict. It's based on avery simple idea that manages anArray
of multiple loading states. Thebuilt-in loader component listens its registered loader and immediately become loading state.
React has its own Suspense feature to manage all the async works. For now it only supports code-splitting (not data-fetching).
useWait
allows you to manage waiting experiences much more explicitly andnot only for Promised/async patterns but also complete loading management.
Here's a quick overview that what'suseWait
for:
import{useWait,Waiter}from"react-wait";functionA(){const{ isWaiting}=useWait();return(<div>{isWaiting("creating user") ?"Creating User..." :"Nothing happens"}</div>);}functionB(){const{ anyWaiting}=useWait();return(<div>{anyWaiting() ?"Something happening on app..." :"Nothing happens"}</div>);}functionC(){const{ startWaiting, endWaiting, isWaiting}=useWait();functioncreateUser(){startWaiting("creating user");// Faking the async work:setTimeout(()=>{endWaiting("creating user");},1000);}return(<buttondisabled={isWaiting("creating user")}onClick={createUser}><Waiton="creating user"fallback={<Spinner/>}> Create User</Wait></button>);}ReactDOM.render(<Waiter><C/></Waiter>,document.getElementById("root"));
If you are atry and learn developer, you can start trying thereact-wait now usingcodesandbox.io.
yarn add react-wait
import{Waiter,useWait}from"react-wait";functionUserCreateButton(){const{ startWaiting, endWaiting, isWaiting, Wait}=useWait();return(<buttononClick={()=>startWaiting("creating user")}disabled={isWaiting("creating user")}><Waiton="creating user"fallback={<div>Creating user!</div>}> Create User</Wait></button>);}
And you should wrap yourApp
withWaiter
component. It's actually aContext.Provider
that provides a loading context to the component tree.
constrootElement=document.getElementById("root");ReactDOM.render(<Waiter><App/></Waiter>,rootElement);
$ yarn add react-wait# or if you using npm$ npm install react-wait
react-wait provides some helpers to you to use in your templates.
Returns boolean value if any loader exists in context.
const{ anyWaiting}=useWait();return<buttondisabled={anyWaiting()}>Disabled while waiting</button>;
Returns boolean value if given loader exists in context.
const{ isWaiting}=useWait();return(<buttondisabled={isWaiting("creating user")}> Disabled while creating user</button>);
Starts the given waiter.
const{ startWaiting}=useWait();return<buttononClick={()=>startWaiting("message")}>Start</button>;
Stops the given waiter.
const{ end}=useWait();return<buttononClick={()=>endWaiting("message")}>Stop</button>;
functionComponent(){const{ Wait}=useWait();return(<Waiton="the waiting message"fallback={<div>Waiting...</div>}> The content after waiting done</Wait>);}
Better example for abutton
with loading state:
<buttondisabled={isWaiting("creating user")}><Waiton="creating user"fallback={<div>Creating User...</div>}> Create User</Wait></button>
With reusable loader components, you will be able to use custom loader components as example below. This will allow you to create betteruser loading experience.
functionSpinner(){return<imgsrc="spinner.gif"/>;}
Now you can use your spinner everywhere usingwaiting
attribute:
<buttondisabled={isWaiting("creating user")}><Waiton="creating user"fallback={<Spinner/>}> Create User</Wait></button>
To keep your code DRY you can create aWaiting Context
usingcreateWaitingContext
.
functionCreateUserButton(){const{ createWaitingContext}=useWait();// All methods will be curried with "creating user" on.const{ startWaiting, endWaiting, isWaiting, Wait}=createWaitingContext("creating user");functioncreateUser(){startWaiting();setTimeout(endWaiting,1000);}return(<Buttondisabled={isWaiting()}onClick={createUser}><Waitfallback="Creating User...">Create User</Wait></Button>);}
- Fatih Kadir Akın, (creator)
Sincereact-wait based on a very simple idea, it can be implemented on other frameworks.
- vue-wait: Multiple Process Loader Management for Vue.
- dom-wait: Multiple Process Loader Management for vanilla JavaScript.
MIT ©Fatih Kadir Akın
About
Complex Loader Management Hook for React Applications