File tree Expand file tree Collapse file tree 6 files changed +101
-0
lines changed Expand file tree Collapse file tree 6 files changed +101
-0
lines changed Original file line number Diff line number Diff line change 119
119
- [ ** State** ] ( ./docs/State.md )
120
120
- [ ` createMemo ` ] ( ./docs/createMemo.md ) &mdash ; factory of memoized hooks.
121
121
- [ ` createReducer ` ] ( ./docs/createReducer.md ) &mdash ; factory of reducer hooks with custom middleware.
122
+ - [ ` useDefault ` ] ( ./docs/useDefault.md ) &mdash ; returns the default value when state is ` null ` or ` undefined ` .
122
123
- [ ` useGetSet ` ] ( ./docs/useGetSet.md ) &mdash ; returns state getter ` get() ` instead of raw state.
123
124
- [ ` useGetSetState ` ] ( ./docs/useGetSetState.md ) &mdash ; as if [ ` useGetSet ` ] ( ./docs/useGetSet.md ) and [ ` useSetState ` ] ( ./docs/useSetState.md ) had a baby.
124
125
- [ ` usePrevious ` ] ( ./docs/usePrevious.md ) &mdash ; returns the previous state or props.
Original file line number Diff line number Diff line change
1
+ # ` useDefault `
2
+
3
+ React state hook that returns the default value when state is null or undefined.
4
+
5
+ ## Usage
6
+
7
+ ``` jsx
8
+ import {useDefault } from ' react-use' ;
9
+
10
+ const Demo = () => {
11
+ const initialUser = { name: ' Marshall' }
12
+ const defaultUser = { name: ' Mathers' }
13
+ const [user , setUser ] = useDefault (defaultUser, initialUser);
14
+
15
+ return (
16
+ < div>
17
+ < div> User: {user .name }< / div>
18
+ < input onChange= {e => setUser ({ name: e .target .value })} / >
19
+ < button onClick= {() => setUser (null )}> set to null < / button>
20
+ < / div>
21
+ );
22
+ };
23
+ ```
Original file line number Diff line number Diff line change
1
+ import { storiesOf } from '@storybook/react' ;
2
+ import * as React from 'react' ;
3
+ import { useDefault } from '..' ;
4
+ import ShowDocs from './util/ShowDocs' ;
5
+
6
+ const Demo = ( ) => {
7
+ const initialUser = { name : 'Marshall' } ;
8
+ const defaultUser = { name : 'Mathers' } ;
9
+ const [ user , setUser ] = useDefault ( defaultUser , initialUser ) ;
10
+
11
+ return (
12
+ < div >
13
+ < div > User: { user . name } </ div >
14
+ < input onChange = { e => setUser ( { name : e . target . value } ) } />
15
+ < button onClick = { ( ) => setUser ( null ) } > set to null</ button >
16
+ </ div >
17
+ ) ;
18
+ } ;
19
+
20
+ storiesOf ( 'State|useDefault' , module )
21
+ . add ( 'Docs' , ( ) => < ShowDocs md = { require ( '../../docs/useDefault.md' ) } /> )
22
+ . add ( 'Demo' , ( ) => < Demo /> ) ;
Original file line number Diff line number Diff line change
1
+ import { act , cleanup , renderHook } from 'react-hooks-testing-library' ;
2
+ import useDefault from '../useDefault' ;
3
+
4
+ afterEach ( cleanup ) ;
5
+
6
+ describe ( 'useDefault' , ( ) => {
7
+ test ( 'should be defined' , ( ) => {
8
+ expect ( useDefault ) . toBeDefined ( ) ;
9
+ } ) ;
10
+
11
+ const hook = renderHook ( ( ) => useDefault ( { name : 'Marshall' } , { name : '' } ) ) ;
12
+
13
+ test ( 'should return initial state on initial render' , ( ) => {
14
+ expect ( hook . result . current [ 0 ] . name ) . toBe ( '' ) ;
15
+ } ) ;
16
+
17
+ test ( 'should update state with correct value' , ( ) => {
18
+ hook . rerender ( ) ;
19
+ act ( ( ) => {
20
+ hook . result . current [ 1 ] ( { name : 'Mathers' } ) ;
21
+ } ) ;
22
+
23
+ expect ( hook . result . current [ 0 ] . name ) . toBe ( 'Mathers' ) ;
24
+ } ) ;
25
+
26
+ test ( 'should return the default value when updated state is nil' , ( ) => {
27
+ hook . rerender ( ) ;
28
+ act ( ( ) => {
29
+ hook . result . current [ 1 ] ( null ) ;
30
+ } ) ;
31
+
32
+ expect ( hook . result . current [ 0 ] . name ) . toBe ( 'Marshall' ) ;
33
+
34
+ act ( ( ) => {
35
+ hook . result . current [ 1 ] ( undefined ) ;
36
+ } ) ;
37
+
38
+ expect ( hook . result . current [ 0 ] . name ) . toBe ( 'Marshall' ) ;
39
+ } ) ;
40
+ } ) ;
Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ import useCounter from './useCounter';
13
13
import useCss from './useCss' ;
14
14
import useDebounce from './useDebounce' ;
15
15
import useDeepCompareEffect from './useDeepCompareEffect' ;
16
+ import useDefault from './useDefault' ;
16
17
import useDrop from './useDrop' ;
17
18
import useDropArea from './useDropArea' ;
18
19
import useEffectOnce from './useEffectOnce' ;
@@ -94,6 +95,7 @@ export {
94
95
useCss ,
95
96
useDebounce ,
96
97
useDeepCompareEffect ,
98
+ useDefault ,
97
99
useDrop ,
98
100
useDropArea ,
99
101
useEffectOnce ,
Original file line number Diff line number Diff line change
1
+ import { useState } from 'react' ;
2
+
3
+ const useDefault = ( defaultValue , initialValue ) : [ any , ( nextValue ?: any ) => void ] => {
4
+ const [ value , setValue ] = useState ( initialValue ) ;
5
+
6
+ if ( value === undefined || value === null ) {
7
+ return [ defaultValue , setValue ] ;
8
+ }
9
+
10
+ return [ value , setValue ] ;
11
+ } ;
12
+
13
+ export default useDefault ;
You can’t perform that action at this time.
0 commit comments