-
-
Notifications
You must be signed in to change notification settings - Fork 2k
/
useWatch.ts
109 lines (101 loc) 路 3.31 KB
/
useWatch.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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import * as React from 'react';
import { useFormContext } from './useFormContext';
import isUndefined from './utils/isUndefined';
import isString from './utils/isString';
import generateId from './logic/generateId';
import get from './utils/get';
import isArray from './utils/isArray';
import isObject from './utils/isObject';
import {
DeepPartial,
UseWatchOptions,
FieldValues,
UnpackNestedValue,
Control,
} from './types';
export function useWatch<TWatchFieldValues extends FieldValues>(props: {
defaultValue?: UnpackNestedValue<DeepPartial<TWatchFieldValues>>;
control?: Control;
}): UnpackNestedValue<DeepPartial<TWatchFieldValues>>;
export function useWatch<TWatchFieldValue extends any>(props: {
name: string;
control?: Control;
}): undefined | UnpackNestedValue<TWatchFieldValue>;
export function useWatch<TWatchFieldValue extends any>(props: {
name: string;
defaultValue: UnpackNestedValue<TWatchFieldValue>;
control?: Control;
}): UnpackNestedValue<TWatchFieldValue>;
export function useWatch<TWatchFieldValues extends FieldValues>(props: {
name: string[];
defaultValue?: UnpackNestedValue<DeepPartial<TWatchFieldValues>>;
control?: Control;
}): UnpackNestedValue<DeepPartial<TWatchFieldValues>>;
export function useWatch<TWatchFieldValues>({
control,
name,
defaultValue,
}: UseWatchOptions): TWatchFieldValues {
const methods = useFormContext();
if (process.env.NODE_ENV !== 'production') {
if (!control && !methods) {
throw new Error(
'馃搵 useWatch is missing `control` prop. https://react-hook-form.com/api#useWatch',
);
}
if (name === '') {
console.warn(
'馃搵 useWatch is missing `name` attribute. https://react-hook-form.com/api#useWatch',
);
}
}
const {
watchFieldsHookRef,
watchFieldsHookRenderRef,
watchInternal,
defaultValuesRef,
} = control || methods.control;
const [value, setValue] = React.useState<unknown>(
isUndefined(defaultValue)
? isString(name)
? get(defaultValuesRef.current, name)
: isArray(name)
? name.reduce(
(previous, inputName) => ({
...previous,
[inputName]: get(defaultValuesRef.current, inputName),
}),
{},
)
: defaultValuesRef.current
: defaultValue,
);
const idRef = React.useRef<string>();
const defaultValueRef = React.useRef(defaultValue);
const updateWatchValue = React.useCallback(() => {
const value = watchInternal(name, defaultValueRef.current, idRef.current);
setValue(
isObject(value) ? { ...value } : isArray(value) ? [...value] : value,
);
}, [setValue, watchInternal, defaultValueRef, name, idRef]);
React.useEffect(() => {
const id = (idRef.current = generateId());
const watchFieldsHookRender = watchFieldsHookRenderRef.current;
const watchFieldsHook = watchFieldsHookRef.current;
watchFieldsHook[id] = new Set();
watchFieldsHookRender[id] = updateWatchValue;
watchInternal(name, defaultValueRef.current, id);
return () => {
delete watchFieldsHook[id];
delete watchFieldsHookRender[id];
};
}, [
name,
updateWatchValue,
watchFieldsHookRenderRef,
watchFieldsHookRef,
watchInternal,
defaultValueRef,
]);
return (isUndefined(value) ? defaultValue : value) as TWatchFieldValues;
}