-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathuse-controlled-value.ts
44 lines (40 loc) · 1.05 KB
/
use-controlled-value.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
type Props< T > = {
defaultValue?: T;
value?: T;
onChange?: ( value: T ) => void;
};
/**
* Simplified and improved implementation of useControlledState.
*
* @param props
* @param props.defaultValue
* @param props.value
* @param props.onChange
* @return The controlled value and the value setter.
*/
export function useControlledValue< T >( {
defaultValue,
onChange,
value: valueProp,
}: Props< T > ) {
const hasValue = typeof valueProp !== 'undefined';
const initialValue = hasValue ? valueProp : defaultValue;
const [ state, setState ] = useState( initialValue );
const value = hasValue ? valueProp : state;
let setValue: ( nextValue: T ) => void;
if ( hasValue && typeof onChange === 'function' ) {
setValue = onChange;
} else if ( ! hasValue && typeof onChange === 'function' ) {
setValue = ( nextValue ) => {
onChange( nextValue );
setState( nextValue );
};
} else {
setValue = setState;
}
return [ value, setValue as typeof setState ] as const;
}