react-hook-form 7.19.5 → 7.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -103,49 +103,35 @@ var shouldRenderFormState = (formStateData, _proxyFormState, isRoot) => {
103
103
 
104
104
  var convertToArrayPayload = (value) => (Array.isArray(value) ? value : [value]);
105
105
 
106
- var shouldSubscribeByName = (name, signalName) => !name ||
107
- !signalName ||
108
- name === signalName ||
109
- convertToArrayPayload(name).some((currentName) => currentName &&
110
- (currentName.startsWith(signalName) ||
111
- signalName.startsWith(currentName)));
112
-
113
- const tearDown = (_subscription) => {
114
- if (_subscription.current) {
115
- _subscription.current.unsubscribe();
116
- _subscription.current = undefined;
117
- }
118
- };
119
- const updateSubscriptionProps = ({ _subscription, _props }) => {
120
- if (_props.current.disabled) {
121
- tearDown(_subscription);
122
- }
123
- else if (!_subscription.current) {
124
- _subscription.current = _props.current.subject.subscribe({
125
- next: _props.current.callback,
126
- });
127
- }
128
- };
106
+ var shouldSubscribeByName = (name, signalName, exact) => exact && signalName
107
+ ? name === signalName
108
+ : !name ||
109
+ !signalName ||
110
+ name === signalName ||
111
+ convertToArrayPayload(name).some((currentName) => currentName &&
112
+ (currentName.startsWith(signalName) ||
113
+ signalName.startsWith(currentName)));
114
+
129
115
  function useSubscribe(props) {
130
- const _subscription = React.useRef();
131
116
  const _props = React.useRef(props);
132
117
  _props.current = props;
133
- updateSubscriptionProps({
134
- _subscription,
135
- _props,
136
- });
137
118
  React.useEffect(() => {
138
- updateSubscriptionProps({
139
- _subscription,
140
- _props,
141
- });
142
- return () => tearDown(_subscription);
143
- }, []);
119
+ const tearDown = (subscription) => {
120
+ if (subscription) {
121
+ subscription.unsubscribe();
122
+ }
123
+ };
124
+ const subscription = !props.disabled &&
125
+ _props.current.subject.subscribe({
126
+ next: _props.current.callback,
127
+ });
128
+ return () => tearDown(subscription);
129
+ }, [props.disabled]);
144
130
  }
145
131
 
146
132
  function useFormState(props) {
147
133
  const methods = useFormContext();
148
- const { control = methods.control, disabled, name } = props || {};
134
+ const { control = methods.control, disabled, name, exact } = props || {};
149
135
  const [formState, updateFormState] = React.useState(control._formState);
150
136
  const _localProxyFormState = React.useRef({
151
137
  isDirty: false,
@@ -159,9 +145,9 @@ function useFormState(props) {
159
145
  _name.current = name;
160
146
  useSubscribe({
161
147
  disabled,
162
- callback: (formState) => shouldSubscribeByName(_name.current, formState.name) &&
163
- shouldRenderFormState(formState, _localProxyFormState.current) &&
164
- updateFormState(Object.assign(Object.assign({}, control._formState), formState)),
148
+ callback: (value) => shouldSubscribeByName(_name.current, value.name, exact) &&
149
+ shouldRenderFormState(value, _localProxyFormState.current) &&
150
+ updateFormState(Object.assign(Object.assign({}, control._formState), value)),
165
151
  subject: control._subjects.state,
166
152
  });
167
153
  return getProxyFormState(formState, control._proxyFormState, _localProxyFormState.current, false);
@@ -185,14 +171,14 @@ function generateWatchOutput(names, _names, formValues, isGlobal) {
185
171
 
186
172
  function useWatch(props) {
187
173
  const methods = useFormContext();
188
- const { control = methods.control, name, defaultValue, disabled, } = props || {};
174
+ const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
189
175
  const _name = React.useRef(name);
190
176
  _name.current = name;
191
177
  useSubscribe({
192
178
  disabled,
193
179
  subject: control._subjects.watch,
194
180
  callback: (formState) => {
195
- if (shouldSubscribeByName(_name.current, formState.name)) {
181
+ if (shouldSubscribeByName(_name.current, formState.name, exact)) {
196
182
  const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
197
183
  updateValue(isUndefined(_name.current)
198
184
  ? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
@@ -213,10 +199,12 @@ function useWatch(props) {
213
199
  function useController(props) {
214
200
  const methods = useFormContext();
215
201
  const { name, control = methods.control, shouldUnregister } = props;
202
+ const isArrayField = isNameInFieldArray(control._names.array, name);
216
203
  const value = useWatch({
217
204
  control,
218
205
  name,
219
206
  defaultValue: get(control._formValues, name, get(control._defaultValues, name, props.defaultValue)),
207
+ exact: !isArrayField,
220
208
  });
221
209
  const formState = useFormState({
222
210
  control,
@@ -235,7 +223,7 @@ function useController(props) {
235
223
  updateMounted(name, true);
236
224
  return () => {
237
225
  const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
238
- if (isNameInFieldArray(control._names.array, name)
226
+ if (isArrayField
239
227
  ? _shouldUnregisterField && !control._stateFlags.action
240
228
  : _shouldUnregisterField) {
241
229
  control.unregister(name, { keepDefaultValue: true });
@@ -244,7 +232,7 @@ function useController(props) {
244
232
  updateMounted(name, false);
245
233
  }
246
234
  };
247
- }, [name, control, shouldUnregister]);
235
+ }, [name, control, isArrayField, shouldUnregister]);
248
236
  return {
249
237
  field: {
250
238
  onChange: (event) => {
@@ -259,7 +247,7 @@ function useController(props) {
259
247
  onBlur: () => {
260
248
  registerProps.onBlur({
261
249
  target: {
262
- value,
250
+ value: get(control._formValues, name),
263
251
  name: name,
264
252
  },
265
253
  type: EVENTS.BLUR,
@@ -347,6 +335,12 @@ var getFocusFieldName = (name, index, options = {}) => options.shouldFocus || is
347
335
  `${name}.${isUndefined(options.focusIndex) ? index : options.focusIndex}.`
348
336
  : '';
349
337
 
338
+ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
339
+ (_names.watchAll ||
340
+ _names.watch.has(name) ||
341
+ [..._names.watch].some((watchName) => name.startsWith(watchName) &&
342
+ /^\.\w+/.test(name.slice(watchName.length))));
343
+
350
344
  var mapCurrentIds = (values, _fieldIds, keyName) => values.map((value, index) => {
351
345
  const output = _fieldIds.current[index];
352
346
  return Object.assign(Object.assign({}, value), (output ? { [keyName]: output[keyName] } : {}));
@@ -507,17 +501,7 @@ const useFieldArray = (props) => {
507
501
  };
508
502
  React.useEffect(() => {
509
503
  control._stateFlags.action = false;
510
- if (control._names.watchAll) {
511
- control._subjects.state.next({});
512
- }
513
- else {
514
- for (const watchField of control._names.watch) {
515
- if (name.startsWith(watchField)) {
516
- control._subjects.state.next({});
517
- break;
518
- }
519
- }
520
- }
504
+ isWatched(name, control._names) && control._subjects.state.next({});
521
505
  if (_actioned.current) {
522
506
  control._executeSchema([name]).then((result) => {
523
507
  const error = get(result.errors, name);
@@ -1114,10 +1098,6 @@ function createFormControl(props = {}) {
1114
1098
  clearTimeout(timer);
1115
1099
  timer = window.setTimeout(() => callback(...args), wait);
1116
1100
  };
1117
- const isFieldWatched = (name, isBlurEvent) => !isBlurEvent &&
1118
- (_names.watchAll ||
1119
- _names.watch.has(name) ||
1120
- _names.watch.has((name.match(/\w+/) || [])[0]));
1121
1101
  const _updateValid = async (shouldSkipRender) => {
1122
1102
  let isValid = false;
1123
1103
  if (_proxyFormState.isValid) {
@@ -1386,7 +1366,7 @@ function createFormControl(props = {}) {
1386
1366
  ? setValues(name, value, options)
1387
1367
  : setFieldValue(name, value, options);
1388
1368
  }
1389
- isFieldWatched(name) && _subjects.state.next({});
1369
+ isWatched(name, _names) && _subjects.state.next({});
1390
1370
  _subjects.watch.next({
1391
1371
  name,
1392
1372
  });
@@ -1405,7 +1385,7 @@ function createFormControl(props = {}) {
1405
1385
  !get(_formState.errors, name) &&
1406
1386
  !field._f.deps) ||
1407
1387
  skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1408
- const isWatched = isFieldWatched(name, isBlurEvent);
1388
+ const watched = isWatched(name, _names, isBlurEvent);
1409
1389
  if (isBlurEvent) {
1410
1390
  field._f.onBlur && field._f.onBlur(event);
1411
1391
  }
@@ -1414,7 +1394,7 @@ function createFormControl(props = {}) {
1414
1394
  }
1415
1395
  set(_formValues, name, fieldValue);
1416
1396
  const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
1417
- const shouldRender = !isEmptyObject(fieldState) || isWatched;
1397
+ const shouldRender = !isEmptyObject(fieldState) || watched;
1418
1398
  !isBlurEvent &&
1419
1399
  _subjects.watch.next({
1420
1400
  name,
@@ -1422,9 +1402,9 @@ function createFormControl(props = {}) {
1422
1402
  });
1423
1403
  if (shouldSkipValidation) {
1424
1404
  return (shouldRender &&
1425
- _subjects.state.next(Object.assign({ name }, (isWatched ? {} : fieldState))));
1405
+ _subjects.state.next(Object.assign({ name }, (watched ? {} : fieldState))));
1426
1406
  }
1427
- !isBlurEvent && isWatched && _subjects.state.next({});
1407
+ !isBlurEvent && watched && _subjects.state.next({});
1428
1408
  validateFields[name] = validateFields[name] ? +1 : 1;
1429
1409
  _proxyFormState.isValidating &&
1430
1410
  _subjects.state.next({
@@ -1838,9 +1818,9 @@ function useForm(props = {}) {
1838
1818
  const control = _formControl.current.control;
1839
1819
  useSubscribe({
1840
1820
  subject: control._subjects.state,
1841
- callback: (formState) => {
1842
- if (shouldRenderFormState(formState, control._proxyFormState, true)) {
1843
- control._formState = Object.assign(Object.assign({}, control._formState), formState);
1821
+ callback: (value) => {
1822
+ if (shouldRenderFormState(value, control._proxyFormState, true)) {
1823
+ control._formState = Object.assign(Object.assign({}, control._formState), value);
1844
1824
  updateFormState(Object.assign({}, control._formState));
1845
1825
  }
1846
1826
  },