@@ -64,8 +64,8 @@ error states, without assumptions about the shape of your data or the type of re
64
64
- [ As a hook] ( #as-a-hook )
65
65
- [ With ` useFetch ` ] ( #with-usefetch )
66
66
- [ As a component] ( #as-a-component )
67
- - [ With helper components] ( #with-helper-components )
68
67
- [ As a factory] ( #as-a-factory )
68
+ - [ With helper components] ( #with-helper-components )
69
69
- [ API] ( #api )
70
70
- [ Options] ( #options )
71
71
- [ Render props] ( #render-props )
@@ -168,6 +168,9 @@ const MyComponent = () => {
168
168
}
169
169
```
170
170
171
+ > Using [ helper components] ( #with-helper-components ) can greatly improve readability of your render functions by not
172
+ > having to write all those conditional returns.
173
+
171
174
Or using the shorthand version:
172
175
173
176
``` jsx
@@ -231,56 +234,90 @@ const MyComponent = () => (
231
234
)
232
235
```
233
236
234
- #### With helper components
237
+ > Using [ helper components] ( #with-helper-components ) can greatly improve readability of your render functions by not
238
+ > having to write all those conditional returns.
235
239
236
- Several [ helper components] ( #helper-components ) are available for better legibility. These don't have to be direct
237
- children of ` <Async> ` , because they use Context, offering full flexibility. You can even use render props and helper
238
- components together.
240
+ ### As a factory
241
+
242
+ You can also create your own component instances, allowing you to preconfigure them with options such as default
243
+ ` onResolve ` and ` onReject ` callbacks.
239
244
240
245
``` jsx
241
- import Async from " react-async"
246
+ import { createInstance } from " react-async"
242
247
243
248
const loadCustomer = ({ customerId }, { signal }) =>
244
249
fetch (` /api/customers/${ customerId} ` , { signal })
245
250
.then (res => (res .ok ? res : Promise .reject (res)))
246
251
.then (res => res .json ())
247
252
253
+ // createInstance takes a defaultProps object and a displayName (both optional)
254
+ const AsyncCustomer = createInstance ({ promiseFn: loadCustomer }, " AsyncCustomer" )
255
+
248
256
const MyComponent = () => (
249
- < Async promiseFn= {loadCustomer} customerId= {1 }>
250
- < Async .Loading > Loading... < / Async .Loading >
251
- < Async .Fulfilled >
252
- {data => (
253
- < div>
254
- < strong> Loaded some data: < / strong>
255
- < pre> {JSON .stringify (data, null , 2 )}< / pre>
256
- < / div>
257
- )}
258
- < / Async .Fulfilled >
259
- < Async .Rejected > {error => ` Something went wrong: ${ error .message } ` }< / Async .Rejected >
260
- < / Async>
257
+ < AsyncCustomer customerId= {1 }>
258
+ < AsyncCustomer .Fulfilled > {customer => ` Hello ${ customer .name } ` }< / AsyncCustomer .Fulfilled >
259
+ < / AsyncCustomer>
261
260
)
262
261
```
263
262
264
- ### As a factory
263
+ ### With helper components
265
264
266
- You can also create your own component instances, allowing you to preconfigure them with options such as default
267
- ` onResolve ` and ` onReject ` callbacks.
265
+ Several [ helper components] ( #helper-components ) are available to improve legibility. They can be used with ` useAsync `
266
+ by passing in the state, or with ` <Async> ` by using Context. Each of these components simply enables or disables
267
+ rendering of its children based on the current state.
268
268
269
269
``` jsx
270
- import { createInstance } from " react-async"
270
+ import { useAsync , Pending , Fulfilled , Rejected } from " react-async"
271
+
272
+ const loadCustomer = async ({ customerId }, { signal }) => {
273
+ // ...
274
+ }
275
+
276
+ const MyComponent = () => {
277
+ const state = useAsync ({ promiseFn: loadCustomer, customerId: 1 })
278
+ return (
279
+ <>
280
+ < Pending state= {state}> Loading... < / Pending>
281
+ < Rejected state= {state}> {error => ` Something went wrong: ${ error .message } ` }< / Rejected>
282
+ < Fulfilled state= {state}>
283
+ {data => (
284
+ < div>
285
+ < strong> Loaded some data: < / strong>
286
+ < pre> {JSON .stringify (data, null , 2 )}< / pre>
287
+ < / div>
288
+ )}
289
+ < / Fulfilled>
290
+ < / >
291
+ )
292
+ }
293
+ ```
294
+
295
+ #### As compounds to <Async >
296
+
297
+ Each of the helper components are also available as static properties of ` <Async> ` . In this case you won't have to pass
298
+ the state object, instead it will be automatically provided through Context.
299
+
300
+ ``` jsx
301
+ import Async from " react-async"
271
302
272
303
const loadCustomer = ({ customerId }, { signal }) =>
273
304
fetch (` /api/customers/${ customerId} ` , { signal })
274
305
.then (res => (res .ok ? res : Promise .reject (res)))
275
306
.then (res => res .json ())
276
307
277
- // createInstance takes a defaultProps object and a displayName (both optional)
278
- const AsyncCustomer = createInstance ({ promiseFn: loadCustomer }, " AsyncCustomer" )
279
-
280
308
const MyComponent = () => (
281
- < AsyncCustomer customerId= {1 }>
282
- < AsyncCustomer .Fulfilled > {customer => ` Hello ${ customer .name } ` }< / AsyncCustomer .Fulfilled >
283
- < / AsyncCustomer>
309
+ < Async promiseFn= {loadCustomer} customerId= {1 }>
310
+ < Async .Loading > Loading... < / Async .Loading >
311
+ < Async .Fulfilled >
312
+ {data => (
313
+ < div>
314
+ < strong> Loaded some data: < / strong>
315
+ < pre> {JSON .stringify (data, null , 2 )}< / pre>
316
+ < / div>
317
+ )}
318
+ < / Async .Fulfilled >
319
+ < Async .Rejected > {error => ` Something went wrong: ${ error .message } ` }< / Async .Rejected >
320
+ < / Async>
284
321
)
285
322
```
286
323
@@ -554,17 +591,27 @@ invoked after the state update is completed. Returns the error to enable chainin
554
591
React Async provides several helper components that make your JSX more declarative and less cluttered.
555
592
They don't have to be direct children of ` <Async> ` and you can use the same component several times.
556
593
557
- ### ` <Async.Initial> `
594
+ ### ` <Initial> ` / ` < Async.Initial>`
558
595
559
596
Renders only while the deferred promise is still waiting to be run, or you have not provided any promise.
560
597
561
598
#### Props
562
599
563
- - ` persist ` ` boolean ` Show until we have data, even while loading or when an error occurred. By default it hides as soon as the promise starts loading.
564
600
- ` children ` ` function(state: Object): Node | Node ` Render function or React Node.
601
+ - ` state ` ` object ` Async state object (return value of ` useAsync() ` ).
602
+ - ` persist ` ` boolean ` Show until we have data, even while loading or when an error occurred. By default it hides as soon as the promise starts loading.
565
603
566
604
#### Examples
567
605
606
+ ``` jsx
607
+ const state = useAsync (... )
608
+ return (
609
+ < Initial state= {state}>
610
+ < p> This text is only rendered while ` run` has not yet been invoked on ` deferFn` .< / p>
611
+ < / Initial>
612
+ )
613
+ ```
614
+
568
615
``` jsx
569
616
< Async deferFn= {deferFn}>
570
617
< Async .Initial >
@@ -587,19 +634,29 @@ Renders only while the deferred promise is still waiting to be run, or you have
587
634
< / Async .Initial >
588
635
```
589
636
590
- ### ` <Async.Pending> `
637
+ ### ` <Pending> ` / ` < Async.Pending>`
591
638
592
639
This component renders only while the promise is pending (aka loading) (unsettled).
593
640
594
641
Alias: ` <Async.Loading> `
595
642
596
643
#### Props
597
644
598
- - ` initial ` ` boolean ` Show only on initial load (when ` data ` is ` undefined ` ).
599
645
- ` children ` ` function(state: Object): Node | Node ` Render function or React Node.
646
+ - ` state ` ` object ` Async state object (return value of ` useAsync() ` ).
647
+ - ` initial ` ` boolean ` Show only on initial load (when ` data ` is ` undefined ` ).
600
648
601
649
#### Examples
602
650
651
+ ``` jsx
652
+ const state = useAsync (... )
653
+ return (
654
+ < Pending state= {state}>
655
+ < p> This text is only rendered while performing the initial load.< / p>
656
+ < / Pending>
657
+ )
658
+ ```
659
+
603
660
``` jsx
604
661
< Async .Pending initial>
605
662
< p> This text is only rendered while performing the initial load.< / p>
@@ -610,19 +667,29 @@ Alias: `<Async.Loading>`
610
667
< Async .Pending > {({ startedAt }) => ` Loading since ${ startedAt .toISOString ()} ` }< / Async .Pending >
611
668
```
612
669
613
- ### ` <Async.Fulfilled> `
670
+ ### ` <Fulfilled> ` / ` < Async.Fulfilled>`
614
671
615
672
This component renders only when the promise is fulfilled with data (` data !== undefined ` ).
616
673
617
674
Alias: ` <Async.Resolved> `
618
675
619
676
#### Props
620
677
621
- - ` persist ` ` boolean ` Show old data while loading new data. By default it hides as soon as a new promise starts.
622
678
- ` children ` ` function(data: any, state: Object): Node | Node ` Render function or React Node.
679
+ - ` state ` ` object ` Async state object (return value of ` useAsync() ` ).
680
+ - ` persist ` ` boolean ` Show old data while loading new data. By default it hides as soon as a new promise starts.
623
681
624
682
#### Examples
625
683
684
+ ``` jsx
685
+ const state = useAsync (... )
686
+ return (
687
+ < Fulfilled state= {state}>
688
+ {data => < pre> {JSON .stringify (data)}< / pre> }
689
+ < / Fulfilled>
690
+ )
691
+ ```
692
+
626
693
``` jsx
627
694
< Async .Fulfilled persist> {data => < pre> {JSON .stringify (data)}< / pre> }< / Async .Fulfilled >
628
695
```
@@ -633,17 +700,23 @@ Alias: `<Async.Resolved>`
633
700
< / Async .Fulfilled >
634
701
```
635
702
636
- ### ` <Async.Rejected> `
703
+ ### ` <Rejected> ` / ` < Async.Rejected>`
637
704
638
705
This component renders only when the promise is rejected.
639
706
640
707
#### Props
641
708
642
- - ` persist ` ` boolean ` Show old error while loading new data. By default it hides as soon as a new promise starts.
643
709
- ` children ` ` function(error: Error, state: Object): Node | Node ` Render function or React Node.
710
+ - ` state ` ` object ` Async state object (return value of ` useAsync() ` ).
711
+ - ` persist ` ` boolean ` Show old error while loading new data. By default it hides as soon as a new promise starts.
644
712
645
713
#### Examples
646
714
715
+ ``` jsx
716
+ const state = useAsync (... )
717
+ return < Rejected state= {state}> Oops.< / Rejected>
718
+ ```
719
+
647
720
``` jsx
648
721
< Async .Rejected persist> Oops.< / Async .Rejected >
649
722
```
@@ -652,14 +725,22 @@ This component renders only when the promise is rejected.
652
725
< Async .Rejected > {error => ` Unexpected error: ${ error .message } ` }< / Async .Rejected >
653
726
```
654
727
655
- ### ` <Async.Settled> `
728
+ ### ` <Settled> ` / ` < Async.Settled>`
656
729
657
730
This component renders only when the promise is fulfilled or rejected.
658
731
659
732
#### Props
660
733
661
- - ` persist ` ` boolean ` Show old data or error while loading new data. By default it hides as soon as a new promise starts.
662
734
- ` children ` ` function(state: Object): Node | Node ` Render function or React Node.
735
+ - ` state ` ` object ` Async state object (return value of ` useAsync() ` ).
736
+ - ` persist ` ` boolean ` Show old data or error while loading new data. By default it hides as soon as a new promise starts.
737
+
738
+ #### Examples
739
+
740
+ ``` jsx
741
+ const state = useAsync (... )
742
+ return < Settled state= {state}> {state => ` Finished at ${ state .finishedAt .toISOString ()} ` < / Settled>
743
+ ` ` `
663
744
664
745
## Usage examples
665
746
0 commit comments