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 7676- [ ** Lifecycles** ] ( ./docs/Lifecycles.md )
7777 - [ ` useLifecycles ` ] ( ./docs/useLifecycles.md ) &mdash ; calls ` mount ` and ` unmount ` callbacks.
7878 - [ ` useRefMounted ` ] ( ./docs/useRefMounted.md ) &mdash ; tracks if component is mounted.
79+ - [ ` usePromise ` ] ( ./docs/usePromise.md ) &mdash ; resolves promise only while component is mounted.
7980 - [ ` useLogger ` ] ( ./docs/useLogger.md ) &mdash ; logs in console as component goes through life-cycles.
8081 - [ ` useMount ` ] ( ./docs/useMount.md ) &mdash ; calls ` mount ` callbacks.
8182 - [ ` 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';
3030import useObservable from './useObservable' ;
3131import useOrientation from './useOrientation' ;
3232import useOutsideClick from './useOutsideClick' ;
33+ import usePromise from './usePromise' ;
3334import useRaf from './useRaf' ;
3435import useRefMounted from './useRefMounted' ;
3536import useSessionStorage from './useSessionStorage' ;
@@ -80,6 +81,7 @@ export {
8081 useObservable ,
8182 useOrientation ,
8283 useOutsideClick ,
84+ usePromise ,
8385 useRaf ,
8486 useRefMounted ,
8587 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