react-hook-use-async
Give me an async task, I'll give you its insights!
Table of Contents
- Features
- Installation
- Problem
- Examples
- API
- Feature Comparison
- Migrating from v1 to v2
- FAQ
- Demo
- License
Features
- Simple and flexible!
- Render async task's result without headache.
- Get notified when the async task is complete via
onSuccess()
,onError()
,onCancel()
callbacks. - Support automatically and on-demand re-execute via
execute()
. - Support automatically and on-demand cancellation via
cancel()
.
Installation
$ npm install --save react-hook-use-async
Problem
Async task is a very common stuff in application. For example, fetch todo list, follow a person, upload images... and we need a convenient way to execute an async task and render its result when the task is complete. This package provides a convenient hook to deal with them. Let's see examples and FAQ below.
Examples
Fetching user
import useAsync from 'react-hook-use-async'; { const url = `http://example.com/fetch-user?id=`; return ;} { const task = ; return <div> taskisPending && <div> <div>Fetching...</div> <button ="button" => Cancel </button> </div> taskerror && <div>Error: taskerrormessage</div> taskresult && <div> <div>User: taskresultname</div> <button ="button" = = > Refetch </button> </div> </div> ;}
Following user
import useAsync from 'react-hook-use-async'; { const url = 'http://example.com/follow-user'; const config = method: 'POST' body: JSON ; return ;} { const task = ; return <button ="button" = => Follow </button> ;}
Get notified when task is complete
import useAsync from 'react-hook-use-async'; { const task = ; return <button ="button" = => Follow </button> ;}
Providing custom cancellation
import useAsync Task from 'react-hook-use-async'; { const url = `http://example.com/fetch-user?id=`; const controller = typeof AbortController !== 'undefined' ? : null; const config = signal: controller && controllersignal ; const promise = ; const cancel = controller && controller; return promise cancel;} { const task = ; ...}
Debouncing search
import useAsync Task from 'react-hook-use-async'; { const url = `http://example.com/fetch-articles?query=`; const controller = typeof AbortController !== 'undefined' ? : null; const config = signal: controller && controllersignal ; let timeoutId = null; const promise = resolve reject timeoutId = ; ; const cancel = timeoutId && ; controller && controller; ; return promise cancel;} { const task = ; ...}
API
useAsync
const // async task error, default: undefined error // async task result, default: undefined result // promise of current async task, default: undefined promise // async task is pending or not, default: false isPending // cancel current async task on-demand cancel // execute current async task on-demand execute} = ;
Feature Comparison
Feature | useAsync() | useAsync() (isOnDemand = true) |
---|---|---|
Execute on mount | ✓ | |
Re-execute on inputs changes | ✓ | |
Re-execute on-demand | ✓ | ✓ |
Cancel on unmount | ✓ | ✓ |
Cancel on re-execute | ✓ | ✓ |
Cancel on-demand | ✓ | ✓ |
Get notified when task is complete | ✓ | ✓ |
Migrating from v1 to v2
- Missing
useAsyncOnDemand()
hook. UseuseAsync()
withisOnDemand = true
. - Missing
injection
as second argument ofcreateTask()
. See Providing custom cancellation if you want to cancel request usingfetch()
API. I drop this because of two reason. First, an async task can be anything, not only about data fetching. Provideinjection
for every calls can be annoying. Last, in v1, I supportedfetch()
API only, but in fact, any libraries can be used, such asaxios
,request
... So it's not great. Instead, in v2, I provide you a convenient way to put anycancellation
method to maximize usability.
FAQ
When the async task will be executed?
Let me show you two common use cases:
- Data fetching - Data should be fetched on the component gets mounted and inputs changes, such as apply filters using form. You also want to put a
Fetch
button to let you fetch data on-demand whenever you want. In this case, you must useuseAsync()
hook with proactive mode. - Click-to-action-button - You don't want any automatic mechanism. You want to click a button to do something, such as follow a person or you want to refetch data after you delete a data item. In this case, you must use
useAsync()
hook with on-demand mode.
Why I got infinite re-fetch loop when using useAsync() hook?
Be sure inputs
doesn't change in every render. Understanding by examples:
{ // your `inputs`: [ { id } ] // BUT `{ id }` is always new in every render! const task = ;}
Why is there no new async task execution when inputs changes?
If you use useAsync()
hook in proactive mode, be sure inputs
changes and size of inputs
must be the same between renders.
{ // first render: ids = [1, 2, 3], inputs = [1, 2, 3] // second render: ids = [1, 2], inputs = [1, 2] // size changes => don't execute new async task! const task = ;}
If you use useAsync()
hook in on-demand mode, you must execute on-demand. See below for details.
Why is there no new async task execution when createTask() changes every render?
Because of convenient. Sometimes you might want to write code like this and you don't expect re-execution happens:
{ // createTask() changes every render! const task = ; // DO NOT use write this code! // const task = useAsync(() => doSomething(id), []);}
Make createTask()
depends on inputs
as param, move it out of React component if possible for clarification.
What happens when inputs changes when using useAsync() hook in on-demand mode?
No execution at all. When you execute on-demand, the latest inputs
will be used to create a new async task.
Can I manually execute an async task at any time?
Yes. Via execute()
function in useAsync()
result.
{ const execute = ;}
Is cancellation is supported?
Yes. An async task will be canceled before a new async task to be executed or when the component gets unmounted.
Can I manually cancel the async task at any time?
Yes. Via cancel()
function in useAsync()
result.
{ const cancel = ;}
What happens when isOnDemand changes?
Nothing happens.
When we get notified about completed task via onSuccess(), onError() or onCancel(), which version of callback is used?
No matter how often callback changes, its version in the same execution render will be used.
Demo
- Website: https://wecodenow-react-hook-use-async.stackblitz.io
- Playground: https://stackblitz.com/edit/wecodenow-react-hook-use-async
License
MIT