File tree Expand file tree Collapse file tree 5 files changed +91
-0
lines changed Expand file tree Collapse file tree 5 files changed +91
-0
lines changed Original file line number Diff line number Diff line change 76
76
- [ ** Lifecycles** ] ( ./docs/Lifecycles.md )
77
77
- [ ` useLifecycles ` ] ( ./docs/useLifecycles.md ) &mdash ; calls ` mount ` and ` unmount ` callbacks.
78
78
- [ ` useRefMounted ` ] ( ./docs/useRefMounted.md ) &mdash ; tracks if component is mounted.
79
+ - [ ` usePromise ` ] ( ./docs/usePromise.md ) &mdash ; resolves promise only while component is mounted.
79
80
- [ ` useLogger ` ] ( ./docs/useLogger.md ) &mdash ; logs in console as component goes through life-cycles.
80
81
- [ ` useMount ` ] ( ./docs/useMount.md ) &mdash ; calls ` mount ` callbacks.
81
82
- [ ` useUnmount ` ] ( ./docs/useUnmount.md ) &mdash ; calls ` unmount ` callbacks.
Original file line number Diff line number Diff line change
1
+ # ` usePromise `
2
+
3
+ React Lifecycle hook that returns a helper function for wrapping promises.
4
+ Promises wrapped with this function will resolve only when component is mounted.
5
+
6
+
7
+ ## Usage
8
+
9
+ ``` jsx
10
+ import {usePromise } from ' react-use' ;
11
+
12
+ const Demo = ({promise}) => {
13
+ const mounted = usePromise ();
14
+ const [value , setValue ] = useState ();
15
+
16
+ useEffect (() => {
17
+ (async () => {
18
+ const value = await mounted (promise);
19
+ // This line will not execute if <Demo> component gets unmounted.
20
+ setValue (value);
21
+ })();
22
+ });
23
+ };
24
+ ```
Original file line number Diff line number Diff line change
1
+ import { storiesOf } from '@storybook/react' ;
2
+ import * as React from 'react' ;
3
+ import { usePromise , useBoolean , useNumber } from '..' ;
4
+ import ShowDocs from '../util/ShowDocs' ;
5
+
6
+ const { useState, useEffect} = React ;
7
+
8
+ const DemoInner = ( { promise} ) => {
9
+ const safePromise = usePromise ( ) ;
10
+ const [ value , setValue ] = useState < number > ( - 1 ) ;
11
+ useEffect ( ( ) => {
12
+ safePromise ( promise ) . then ( setValue ) ;
13
+ } , [ promise ] ) ;
14
+
15
+ return (
16
+ < div >
17
+ { value === - 1 ? 'Resolving value...' : 'Value: ' + value }
18
+ </ div >
19
+ ) ;
20
+ } ;
21
+
22
+ const Demo = ( ) => {
23
+ const [ mounted , toggleMounted ] = useBoolean ( true ) ;
24
+ const [ num , { inc} ] = useNumber ( ) ;
25
+ const promise = new Promise ( r => setTimeout ( ( ) => r ( num ) , 1_000 ) ) ;
26
+
27
+ return (
28
+ < div >
29
+ < p > This demo provides a number in a promise that resolves in 1sec to a child component.</ p >
30
+ < button onClick = { ( ) => toggleMounted ( ) } > { mounted ? 'Unmount' : 'Mount' } </ button >
31
+ < button onClick = { ( ) => inc ( ) } > Increment ({ num } )</ button >
32
+ < br />
33
+ { mounted && < DemoInner promise = { promise } /> }
34
+ </ div >
35
+ ) ;
36
+ } ;
37
+
38
+ storiesOf ( 'Lifecycles|usePromise' , module )
39
+ . add ( 'Docs' , ( ) => < ShowDocs md = { require ( '../../docs/usePromise.md' ) } /> )
40
+ . add ( 'Demo' , ( ) =>
41
+ < Demo />
42
+ )
Original file line number Diff line number Diff line change @@ -30,6 +30,7 @@ import useNumber from './useNumber';
30
30
import useObservable from './useObservable' ;
31
31
import useOrientation from './useOrientation' ;
32
32
import useOutsideClick from './useOutsideClick' ;
33
+ import usePromise from './usePromise' ;
33
34
import useRaf from './useRaf' ;
34
35
import useRefMounted from './useRefMounted' ;
35
36
import useSessionStorage from './useSessionStorage' ;
@@ -80,6 +81,7 @@ export {
80
81
useObservable ,
81
82
useOrientation ,
82
83
useOutsideClick ,
84
+ usePromise ,
83
85
useRaf ,
84
86
useRefMounted ,
85
87
useSessionStorage ,
Original file line number Diff line number Diff line change
1
+ import { useCallback } from 'react' ;
2
+ import useRefMounted from './useRefMounted' ;
3
+
4
+ export type UsePromise = ( ) => < T > ( promise : Promise < T > ) => Promise < T > ;
5
+
6
+ const usePromise : UsePromise = ( ) => {
7
+ const refMounted = useRefMounted ( ) ;
8
+ return useCallback ( < T > ( promise : Promise < T > ) : Promise < T > =>
9
+ new Promise < T > ( ( resolve , reject ) => {
10
+ promise . then ( value => {
11
+ if ( refMounted . current ) {
12
+ resolve ( value ) ;
13
+ }
14
+ } , error => {
15
+ if ( refMounted . current ) {
16
+ reject ( error ) ;
17
+ }
18
+ } )
19
+ } ) , [ ] ) ;
20
+ } ;
21
+
22
+ export default usePromise ;
You can’t perform that action at this time.
0 commit comments