react-hook-form 7.22.5 → 7.24.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.
Files changed (42) hide show
  1. package/README.md +15 -0
  2. package/dist/index.cjs.js +1 -1
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.mjs +193 -181
  5. package/dist/index.esm.mjs.map +1 -1
  6. package/dist/index.umd.js +1 -1
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/logic/createFormControl.d.ts.map +1 -1
  9. package/dist/types/fieldArray.d.ts +1 -1
  10. package/dist/types/fieldArray.d.ts.map +1 -1
  11. package/dist/types/form.d.ts +6 -5
  12. package/dist/types/form.d.ts.map +1 -1
  13. package/dist/types/index.d.ts +1 -0
  14. package/dist/types/index.d.ts.map +1 -1
  15. package/dist/types/path/common.d.ts +316 -0
  16. package/dist/types/path/common.d.ts.map +1 -0
  17. package/dist/types/path/eager.d.ts +82 -0
  18. package/dist/types/path/eager.d.ts.map +1 -0
  19. package/dist/types/path/index.d.ts +4 -0
  20. package/dist/types/path/index.d.ts.map +1 -0
  21. package/dist/types/utils.d.ts +19 -25
  22. package/dist/types/utils.d.ts.map +1 -1
  23. package/dist/types/validator.d.ts +1 -1
  24. package/dist/types/validator.d.ts.map +1 -1
  25. package/dist/useController.d.ts.map +1 -1
  26. package/dist/useFieldArray.d.ts.map +1 -1
  27. package/dist/useForm.d.ts.map +1 -1
  28. package/dist/useFormState.d.ts.map +1 -1
  29. package/dist/utils/compact.d.ts +1 -1
  30. package/dist/utils/compact.d.ts.map +1 -1
  31. package/dist/utils/get.d.ts.map +1 -1
  32. package/dist/utils/isDateObject.d.ts +1 -1
  33. package/dist/utils/isDateObject.d.ts.map +1 -1
  34. package/dist/utils/live.d.ts.map +1 -1
  35. package/dist/utils/move.d.ts.map +1 -1
  36. package/dist/utils/update.d.ts +1 -1
  37. package/dist/utils/update.d.ts.map +1 -1
  38. package/package.json +11 -11
  39. package/dist/logic/mapCurrentIds.d.ts +0 -6
  40. package/dist/logic/mapCurrentIds.d.ts.map +0 -1
  41. package/dist/logic/mapId.d.ts +0 -4
  42. package/dist/logic/mapId.d.ts.map +0 -1
@@ -2,7 +2,7 @@ import React from 'react';
2
2
 
3
3
  var isCheckBoxInput = (element) => element.type === 'checkbox';
4
4
 
5
- var isDateObject = (data) => data instanceof Date;
5
+ var isDateObject = (value) => value instanceof Date;
6
6
 
7
7
  var isNullOrUndefined = (value) => value == null;
8
8
 
@@ -22,20 +22,20 @@ var getNodeParentName = (name) => name.substring(0, name.search(/.\d/)) || name;
22
22
 
23
23
  var isNameInFieldArray = (names, name) => [...names].some((current) => getNodeParentName(name) === current);
24
24
 
25
- var compact = (value) => (value || []).filter(Boolean);
25
+ var compact = (value) => value.filter(Boolean);
26
26
 
27
27
  var isUndefined = (val) => val === undefined;
28
28
 
29
29
  var get = (obj, path, defaultValue) => {
30
- if (isObject(obj) && path) {
31
- const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => (isNullOrUndefined(result) ? result : result[key]), obj);
32
- return isUndefined(result) || result === obj
33
- ? isUndefined(obj[path])
34
- ? defaultValue
35
- : obj[path]
36
- : result;
30
+ if (!path || !isObject(obj)) {
31
+ return defaultValue;
37
32
  }
38
- return undefined;
33
+ const result = compact(path.split(/[,[\].]+?/)).reduce((result, key) => isNullOrUndefined(result) ? result : result[key], obj);
34
+ return isUndefined(result) || result === obj
35
+ ? isUndefined(obj[path])
36
+ ? defaultValue
37
+ : obj[path]
38
+ : result;
39
39
  };
40
40
 
41
41
  const EVENTS = {
@@ -142,14 +142,20 @@ function useFormState(props) {
142
142
  errors: false,
143
143
  });
144
144
  const _name = React.useRef(name);
145
+ const _mounted = React.useRef(true);
145
146
  _name.current = name;
147
+ const callback = React.useCallback((value) => _mounted.current &&
148
+ shouldSubscribeByName(_name.current, value.name, exact) &&
149
+ shouldRenderFormState(value, _localProxyFormState.current) &&
150
+ updateFormState(Object.assign(Object.assign({}, control._formState), value)), [control, exact]);
146
151
  useSubscribe({
147
152
  disabled,
148
- callback: (value) => shouldSubscribeByName(_name.current, value.name, exact) &&
149
- shouldRenderFormState(value, _localProxyFormState.current) &&
150
- updateFormState(Object.assign(Object.assign({}, control._formState), value)),
153
+ callback,
151
154
  subject: control._subjects.state,
152
155
  });
156
+ React.useEffect(() => () => {
157
+ _mounted.current = false;
158
+ }, []);
153
159
  return getProxyFormState(formState, control._proxyFormState, _localProxyFormState.current, false);
154
160
  }
155
161
 
@@ -185,21 +191,22 @@ function useWatch(props) {
185
191
  const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
186
192
  const _name = React.useRef(name);
187
193
  _name.current = name;
194
+ const callback = React.useCallback((formState) => {
195
+ if (shouldSubscribeByName(_name.current, formState.name, exact)) {
196
+ const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
197
+ updateValue(isUndefined(_name.current) ||
198
+ (isObject(fieldValues) && !objectHasFunction(fieldValues))
199
+ ? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
200
+ ? [...fieldValues]
201
+ : isUndefined(fieldValues)
202
+ ? defaultValue
203
+ : fieldValues);
204
+ }
205
+ }, [control, exact, defaultValue]);
188
206
  useSubscribe({
189
207
  disabled,
190
208
  subject: control._subjects.watch,
191
- callback: (formState) => {
192
- if (shouldSubscribeByName(_name.current, formState.name, exact)) {
193
- const fieldValues = generateWatchOutput(_name.current, control._names, formState.values || control._formValues);
194
- updateValue(isUndefined(_name.current) ||
195
- (isObject(fieldValues) && !objectHasFunction(fieldValues))
196
- ? Object.assign({}, fieldValues) : Array.isArray(fieldValues)
197
- ? [...fieldValues]
198
- : isUndefined(fieldValues)
199
- ? defaultValue
200
- : fieldValues);
201
- }
202
- },
209
+ callback,
203
210
  });
204
211
  const [value, updateValue] = React.useState(isUndefined(defaultValue)
205
212
  ? control._getWatch(name)
@@ -224,9 +231,7 @@ function useController(props) {
224
231
  control,
225
232
  name,
226
233
  });
227
- const _name = React.useRef(name);
228
- _name.current = name;
229
- const registerProps = control.register(name, Object.assign(Object.assign({}, props.rules), { value }));
234
+ const _registerProps = React.useRef(control.register(name, Object.assign(Object.assign({}, props.rules), { value })));
230
235
  React.useEffect(() => {
231
236
  const updateMounted = (name, value) => {
232
237
  const field = get(control._fields, name);
@@ -246,27 +251,27 @@ function useController(props) {
246
251
  }, [name, control, isArrayField, shouldUnregister]);
247
252
  return {
248
253
  field: {
249
- onChange: (event) => {
250
- registerProps.onChange({
254
+ name,
255
+ value,
256
+ onChange: React.useCallback((event) => {
257
+ _registerProps.current.onChange({
251
258
  target: {
252
259
  value: getEventValue(event),
253
260
  name: name,
254
261
  },
255
262
  type: EVENTS.CHANGE,
256
263
  });
257
- },
258
- onBlur: () => {
259
- registerProps.onBlur({
264
+ }, [name]),
265
+ onBlur: React.useCallback(() => {
266
+ _registerProps.current.onBlur({
260
267
  target: {
261
268
  value: get(control._formValues, name),
262
269
  name: name,
263
270
  },
264
271
  type: EVENTS.BLUR,
265
272
  });
266
- },
267
- name,
268
- value,
269
- ref: (elm) => {
273
+ }, [name, control]),
274
+ ref: React.useCallback((elm) => {
270
275
  const field = get(control._fields, name);
271
276
  if (elm && field && elm.focus) {
272
277
  field._f.ref = {
@@ -275,7 +280,7 @@ function useController(props) {
275
280
  reportValidity: () => elm.reportValidity(),
276
281
  };
277
282
  }
278
- },
283
+ }, [name, control]),
279
284
  },
280
285
  formState,
281
286
  fieldState: {
@@ -341,6 +346,14 @@ const focusFieldBy = (fields, callback, fieldsNames) => {
341
346
  }
342
347
  };
343
348
 
349
+ var generateId = () => {
350
+ const d = typeof performance === 'undefined' ? Date.now() : performance.now() * 1000;
351
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
352
+ const r = (Math.random() * 16 + d) % 16 | 0;
353
+ return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
354
+ });
355
+ };
356
+
344
357
  var getFocusFieldName = (name, index, options = {}) => options.shouldFocus || isUndefined(options.shouldFocus)
345
358
  ? options.focusName ||
346
359
  `${name}.${isUndefined(options.focusIndex) ? index : options.focusIndex}.`
@@ -352,23 +365,8 @@ var isWatched = (name, _names, isBlurEvent) => !isBlurEvent &&
352
365
  [..._names.watch].some((watchName) => name.startsWith(watchName) &&
353
366
  /^\.\w+/.test(name.slice(watchName.length))));
354
367
 
355
- var mapCurrentIds = (values, _fieldIds, keyName) => values.map((value, index) => {
356
- const output = _fieldIds.current[index];
357
- return Object.assign(Object.assign({}, value), (output ? { [keyName]: output[keyName] } : {}));
358
- });
359
-
360
- var generateId = () => {
361
- const d = typeof performance === 'undefined' ? Date.now() : performance.now() * 1000;
362
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
363
- const r = (Math.random() * 16 + d) % 16 | 0;
364
- return (c == 'x' ? r : (r & 0x3) | 0x8).toString(16);
365
- });
366
- };
367
-
368
- var mapIds = (values = [], keyName) => values.map((value) => (Object.assign(Object.assign({}, (value[keyName] ? {} : { [keyName]: generateId() })), value)));
369
-
370
368
  function append(data, value) {
371
- return [...convertToArrayPayload(data), ...convertToArrayPayload(value)];
369
+ return [...data, ...convertToArrayPayload(value)];
372
370
  }
373
371
 
374
372
  function cloneObject(data) {
@@ -407,18 +405,16 @@ function insert(data, index, value) {
407
405
  }
408
406
 
409
407
  var moveArrayAt = (data, from, to) => {
410
- if (Array.isArray(data)) {
411
- if (isUndefined(data[to])) {
412
- data[to] = undefined;
413
- }
414
- data.splice(to, 0, data.splice(from, 1)[0]);
415
- return data;
408
+ if (!Array.isArray(data)) {
409
+ return [];
416
410
  }
417
- return [];
411
+ if (isUndefined(data[to])) {
412
+ data[to] = undefined;
413
+ }
414
+ data.splice(to, 0, data.splice(from, 1)[0]);
415
+ return data;
418
416
  };
419
417
 
420
- var omitKeys = (fields, keyName) => fields.map((field = {}) => omit(field, keyName));
421
-
422
418
  function prepend(data, value) {
423
419
  return [...convertToArrayPayload(value), ...convertToArrayPayload(data)];
424
420
  }
@@ -448,100 +444,110 @@ var updateAt = (fieldValues, index, value) => {
448
444
  const useFieldArray = (props) => {
449
445
  const methods = useFormContext();
450
446
  const { control = methods.control, name, keyName = 'id', shouldUnregister, } = props;
451
- const [fields, setFields] = React.useState(mapIds(control._getFieldArray(name), keyName));
447
+ const [fields, setFields] = React.useState(control._getFieldArray(name));
448
+ const ids = React.useRef(control._getFieldArray(name).map(generateId));
452
449
  const _fieldIds = React.useRef(fields);
453
450
  const _name = React.useRef(name);
454
451
  const _actioned = React.useRef(false);
455
452
  _name.current = name;
456
453
  _fieldIds.current = fields;
457
454
  control._names.array.add(name);
455
+ const callback = React.useCallback(({ values, name: fieldArrayName }) => {
456
+ if (fieldArrayName === _name.current || !fieldArrayName) {
457
+ const fieldValues = get(values, _name.current, []);
458
+ setFields(fieldValues);
459
+ ids.current = fieldValues.map(generateId);
460
+ }
461
+ }, []);
458
462
  useSubscribe({
459
- callback: ({ values, name: fieldArrayName }) => {
460
- if (fieldArrayName === _name.current || !fieldArrayName) {
461
- setFields(mapIds(get(values, _name.current), keyName));
462
- }
463
- },
463
+ callback,
464
464
  subject: control._subjects.array,
465
465
  });
466
- const updateValues = React.useCallback((updatedFieldArrayValuesWithKey) => {
467
- const updatedFieldArrayValues = omitKeys(updatedFieldArrayValuesWithKey, keyName);
466
+ const updateValues = React.useCallback((updatedFieldArrayValues) => {
468
467
  _actioned.current = true;
469
468
  set(control._formValues, name, updatedFieldArrayValues);
470
- return updatedFieldArrayValues;
471
- }, [control, name, keyName]);
469
+ }, [control, name]);
472
470
  const append$1 = (value, options) => {
473
471
  const appendValue = convertToArrayPayload(cloneObject(value));
474
- const updatedFieldArrayValuesWithKey = append(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(appendValue, keyName));
475
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
476
- control._names.focus = getFocusFieldName(name, fieldArrayValues.length - 1, options);
477
- setFields(updatedFieldArrayValuesWithKey);
472
+ const updatedFieldArrayValues = append(control._getFieldArray(name), appendValue);
473
+ control._names.focus = getFocusFieldName(name, updatedFieldArrayValues.length - 1, options);
474
+ ids.current = append(ids.current, appendValue.map(generateId));
475
+ setFields(updatedFieldArrayValues);
476
+ updateValues(updatedFieldArrayValues);
478
477
  control._updateFieldArray(name, append, {
479
478
  argA: fillEmptyArray(value),
480
- }, fieldArrayValues);
479
+ }, updatedFieldArrayValues);
481
480
  };
482
481
  const prepend$1 = (value, options) => {
483
- const updatedFieldArrayValuesWithKey = prepend(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), mapIds(convertToArrayPayload(cloneObject(value)), keyName));
484
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
482
+ const prependValue = convertToArrayPayload(cloneObject(value));
483
+ const updatedFieldArrayValues = prepend(control._getFieldArray(name), prependValue);
485
484
  control._names.focus = getFocusFieldName(name, 0, options);
486
- setFields(updatedFieldArrayValuesWithKey);
485
+ ids.current = prepend(ids.current, prependValue.map(generateId));
486
+ setFields(updatedFieldArrayValues);
487
+ updateValues(updatedFieldArrayValues);
487
488
  control._updateFieldArray(name, prepend, {
488
489
  argA: fillEmptyArray(value),
489
- }, fieldArrayValues);
490
+ }, updatedFieldArrayValues);
490
491
  };
491
492
  const remove = (index) => {
492
- const updatedFieldArrayValuesWithKey = removeArrayAt(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index);
493
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
494
- setFields(updatedFieldArrayValuesWithKey);
493
+ const updatedFieldArrayValues = removeArrayAt(control._getFieldArray(name), index);
494
+ ids.current = removeArrayAt(ids.current, index);
495
+ setFields(updatedFieldArrayValues);
496
+ updateValues(updatedFieldArrayValues);
495
497
  control._updateFieldArray(name, removeArrayAt, {
496
498
  argA: index,
497
- }, fieldArrayValues);
499
+ }, updatedFieldArrayValues);
498
500
  };
499
501
  const insert$1 = (index, value, options) => {
500
- const updatedFieldArrayValuesWithKey = insert(mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName), index, mapIds(convertToArrayPayload(cloneObject(value)), keyName));
501
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
502
+ const insertValue = convertToArrayPayload(cloneObject(value));
503
+ const updatedFieldArrayValues = insert(control._getFieldArray(name), index, insertValue);
504
+ updateValues(updatedFieldArrayValues);
502
505
  control._names.focus = getFocusFieldName(name, index, options);
503
- setFields(updatedFieldArrayValuesWithKey);
506
+ ids.current = insert(ids.current, index, insertValue.map(generateId));
507
+ setFields(updatedFieldArrayValues);
504
508
  control._updateFieldArray(name, insert, {
505
509
  argA: index,
506
510
  argB: fillEmptyArray(value),
507
- }, fieldArrayValues);
511
+ }, updatedFieldArrayValues);
508
512
  };
509
513
  const swap = (indexA, indexB) => {
510
- const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
511
- swapArrayAt(updatedFieldArrayValuesWithKey, indexA, indexB);
512
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
513
- setFields(updatedFieldArrayValuesWithKey);
514
+ const updatedFieldArrayValues = control._getFieldArray(name);
515
+ swapArrayAt(updatedFieldArrayValues, indexA, indexB);
516
+ swapArrayAt(ids.current, indexA, indexB);
517
+ setFields(updatedFieldArrayValues);
518
+ updateValues(updatedFieldArrayValues);
514
519
  control._updateFieldArray(name, swapArrayAt, {
515
520
  argA: indexA,
516
521
  argB: indexB,
517
- }, fieldArrayValues, false);
522
+ }, updatedFieldArrayValues, false);
518
523
  };
519
524
  const move = (from, to) => {
520
- const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
521
- moveArrayAt(updatedFieldArrayValuesWithKey, from, to);
522
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
523
- setFields(updatedFieldArrayValuesWithKey);
525
+ const updatedFieldArrayValues = control._getFieldArray(name);
526
+ moveArrayAt(updatedFieldArrayValues, from, to);
527
+ moveArrayAt(ids.current, from, to);
528
+ setFields(updatedFieldArrayValues);
529
+ updateValues(updatedFieldArrayValues);
524
530
  control._updateFieldArray(name, moveArrayAt, {
525
531
  argA: from,
526
532
  argB: to,
527
- }, fieldArrayValues, false);
533
+ }, updatedFieldArrayValues, false);
528
534
  };
529
535
  const update = (index, value) => {
530
- const updatedFieldArrayValuesWithKey = mapCurrentIds(control._getFieldArray(name), _fieldIds, keyName);
531
- const updatedFieldArrayValues = updateAt(updatedFieldArrayValuesWithKey, index, value);
532
- _fieldIds.current = mapIds(updatedFieldArrayValues, keyName);
533
- const fieldArrayValues = updateValues(_fieldIds.current);
534
- setFields(_fieldIds.current);
536
+ const updatedFieldArrayValues = updateAt(control._getFieldArray(name), index, value);
537
+ ids.current = [...updatedFieldArrayValues].map((item, i) => !item || i === index ? generateId() : ids.current[i]);
538
+ setFields([...updatedFieldArrayValues]);
539
+ updateValues(updatedFieldArrayValues);
535
540
  control._updateFieldArray(name, updateAt, {
536
541
  argA: index,
537
542
  argB: value,
538
- }, fieldArrayValues, true, false, false);
543
+ }, updatedFieldArrayValues, true, false);
539
544
  };
540
545
  const replace = (value) => {
541
- const updatedFieldArrayValuesWithKey = mapIds(convertToArrayPayload(value), keyName);
542
- const fieldArrayValues = updateValues(updatedFieldArrayValuesWithKey);
543
- setFields(updatedFieldArrayValuesWithKey);
544
- control._updateFieldArray(name, () => updatedFieldArrayValuesWithKey, {}, fieldArrayValues, true, false, false);
546
+ const updatedFieldArrayValues = convertToArrayPayload(value);
547
+ ids.current = updatedFieldArrayValues.map(generateId);
548
+ updateValues([...updatedFieldArrayValues]);
549
+ setFields([...updatedFieldArrayValues]);
550
+ control._updateFieldArray(name, () => updatedFieldArrayValues, {}, [...updatedFieldArrayValues], true, false);
545
551
  };
546
552
  React.useEffect(() => {
547
553
  control._stateFlags.action = false;
@@ -565,25 +571,24 @@ const useFieldArray = (props) => {
565
571
  focusFieldBy(control._fields, (key) => key.startsWith(control._names.focus));
566
572
  control._names.focus = '';
567
573
  control._proxyFormState.isValid && control._updateValid();
568
- }, [fields, name, control, keyName]);
574
+ }, [fields, name, control]);
569
575
  React.useEffect(() => {
570
576
  !get(control._formValues, name) && set(control._formValues, name, []);
571
577
  return () => {
572
- if (control._options.shouldUnregister || shouldUnregister) {
578
+ (control._options.shouldUnregister || shouldUnregister) &&
573
579
  control.unregister(name);
574
- }
575
580
  };
576
581
  }, [name, control, keyName, shouldUnregister]);
577
582
  return {
578
- swap: React.useCallback(swap, [updateValues, name, control, keyName]),
579
- move: React.useCallback(move, [updateValues, name, control, keyName]),
580
- prepend: React.useCallback(prepend$1, [updateValues, name, control, keyName]),
581
- append: React.useCallback(append$1, [updateValues, name, control, keyName]),
582
- remove: React.useCallback(remove, [updateValues, name, control, keyName]),
583
- insert: React.useCallback(insert$1, [updateValues, name, control, keyName]),
584
- update: React.useCallback(update, [updateValues, name, control, keyName]),
585
- replace: React.useCallback(replace, [updateValues, name, control, keyName]),
586
- fields: fields,
583
+ swap: React.useCallback(swap, [updateValues, name, control]),
584
+ move: React.useCallback(move, [updateValues, name, control]),
585
+ prepend: React.useCallback(prepend$1, [updateValues, name, control]),
586
+ append: React.useCallback(append$1, [updateValues, name, control]),
587
+ remove: React.useCallback(remove, [updateValues, name, control]),
588
+ insert: React.useCallback(insert$1, [updateValues, name, control]),
589
+ update: React.useCallback(update, [updateValues, name, control]),
590
+ replace: React.useCallback(replace, [updateValues, name, control]),
591
+ fields: React.useMemo(() => fields.map((field, index) => (Object.assign(Object.assign({}, field), { [keyName]: ids.current[index] || generateId() }))), [fields, keyName]),
587
592
  };
588
593
  };
589
594
 
@@ -672,7 +677,7 @@ var isWeb = typeof window !== 'undefined' &&
672
677
  typeof window.HTMLElement !== 'undefined' &&
673
678
  typeof document !== 'undefined';
674
679
 
675
- var live = (ref) => isHTMLElement(ref) && document.contains(ref);
680
+ var live = (ref) => isHTMLElement(ref) && ref.isConnected;
676
681
 
677
682
  function baseGet(object, updatePath) {
678
683
  const length = updatePath.slice(0, -1).length;
@@ -1138,24 +1143,25 @@ function createFormControl(props = {}) {
1138
1143
  }
1139
1144
  return isValid;
1140
1145
  };
1141
- const _updateFieldArray = (name, method, args, values = [], shouldSetValues = true, shouldSetFields = true, shouldSetError = true) => {
1146
+ const _updateFieldArray = (name, method, args, values = [], shouldSetValues = true, shouldSetFields = true) => {
1142
1147
  _stateFlags.action = true;
1143
- if (shouldSetFields && get(_fields, name)) {
1148
+ if (shouldSetFields && Array.isArray(get(_fields, name))) {
1144
1149
  const fieldValues = method(get(_fields, name), args.argA, args.argB);
1145
1150
  shouldSetValues && set(_fields, name, fieldValues);
1146
1151
  }
1147
- if (shouldSetError && Array.isArray(get(_formState.errors, name))) {
1152
+ if (_proxyFormState.errors &&
1153
+ shouldSetFields &&
1154
+ Array.isArray(get(_formState.errors, name))) {
1148
1155
  const errors = method(get(_formState.errors, name), args.argA, args.argB);
1149
1156
  shouldSetValues && set(_formState.errors, name, errors);
1150
1157
  unsetEmptyArray(_formState.errors, name);
1151
1158
  }
1152
- if (_proxyFormState.touchedFields && get(_formState.touchedFields, name)) {
1159
+ if (_proxyFormState.touchedFields &&
1160
+ Array.isArray(get(_formState.touchedFields, name))) {
1153
1161
  const touchedFields = method(get(_formState.touchedFields, name), args.argA, args.argB);
1154
- shouldSetValues &&
1155
- set(_formState.touchedFields, name, touchedFields);
1156
- unsetEmptyArray(_formState.touchedFields, name);
1162
+ shouldSetValues && set(_formState.touchedFields, name, touchedFields);
1157
1163
  }
1158
- if (_proxyFormState.dirtyFields || _proxyFormState.isDirty) {
1164
+ if (_proxyFormState.dirtyFields) {
1159
1165
  _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1160
1166
  }
1161
1167
  _subjects.state.next({
@@ -1169,19 +1175,19 @@ function createFormControl(props = {}) {
1169
1175
  _subjects.state.next({
1170
1176
  errors: _formState.errors,
1171
1177
  }));
1172
- const updateValidAndValue = (name, shouldSkipSetValueAs, ref) => {
1178
+ const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
1173
1179
  const field = get(_fields, name);
1174
1180
  if (field) {
1175
- const defaultValue = get(_formValues, name, get(_defaultValues, name));
1181
+ const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
1176
1182
  isUndefined(defaultValue) ||
1177
1183
  (ref && ref.defaultChecked) ||
1178
1184
  shouldSkipSetValueAs
1179
1185
  ? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
1180
1186
  : setFieldValue(name, defaultValue);
1187
+ _stateFlags.mount && _updateValid();
1181
1188
  }
1182
- _stateFlags.mount && _updateValid();
1183
1189
  };
1184
- const updateTouchAndDirty = (name, fieldValue, isCurrentTouched, shouldRender = true) => {
1190
+ const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1185
1191
  let isFieldDirty = false;
1186
1192
  const output = {
1187
1193
  name,
@@ -1192,7 +1198,7 @@ function createFormControl(props = {}) {
1192
1198
  _formState.isDirty = output.isDirty = _getDirty();
1193
1199
  isFieldDirty = isPreviousFormDirty !== output.isDirty;
1194
1200
  }
1195
- if (_proxyFormState.dirtyFields && !isCurrentTouched) {
1201
+ if (_proxyFormState.dirtyFields && (!isBlurEvent || shouldDirty)) {
1196
1202
  const isPreviousFieldDirty = get(_formState.dirtyFields, name);
1197
1203
  const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1198
1204
  isCurrentFieldPristine
@@ -1203,13 +1209,13 @@ function createFormControl(props = {}) {
1203
1209
  isFieldDirty ||
1204
1210
  isPreviousFieldDirty !== get(_formState.dirtyFields, name);
1205
1211
  }
1206
- if (isCurrentTouched && !isPreviousFieldTouched) {
1207
- set(_formState.touchedFields, name, isCurrentTouched);
1212
+ if (isBlurEvent && !isPreviousFieldTouched) {
1213
+ set(_formState.touchedFields, name, isBlurEvent);
1208
1214
  output.touchedFields = _formState.touchedFields;
1209
1215
  isFieldDirty =
1210
1216
  isFieldDirty ||
1211
1217
  (_proxyFormState.touchedFields &&
1212
- isPreviousFieldTouched !== isCurrentTouched);
1218
+ isPreviousFieldTouched !== isBlurEvent);
1213
1219
  }
1214
1220
  isFieldDirty && shouldRender && _subjects.state.next(output);
1215
1221
  return isFieldDirty ? output : {};
@@ -1335,7 +1341,8 @@ function createFormControl(props = {}) {
1335
1341
  ? fieldReference.refs.forEach((checkboxRef) => (checkboxRef.checked = Array.isArray(fieldValue)
1336
1342
  ? !!fieldValue.find((data) => data === checkboxRef.value)
1337
1343
  : fieldValue === checkboxRef.value))
1338
- : (fieldReference.refs[0].checked = !!fieldValue);
1344
+ : fieldReference.refs[0] &&
1345
+ (fieldReference.refs[0].checked = !!fieldValue);
1339
1346
  }
1340
1347
  else {
1341
1348
  fieldReference.refs.forEach((radioRef) => (radioRef.checked = radioRef.value === fieldValue));
@@ -1352,7 +1359,7 @@ function createFormControl(props = {}) {
1352
1359
  }
1353
1360
  }
1354
1361
  (options.shouldDirty || options.shouldTouch) &&
1355
- updateTouchAndDirty(name, fieldValue, options.shouldTouch);
1362
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1356
1363
  options.shouldValidate && trigger(name);
1357
1364
  };
1358
1365
  const setValues = (name, value, options) => {
@@ -1414,13 +1421,13 @@ function createFormControl(props = {}) {
1414
1421
  !field._f.deps) ||
1415
1422
  skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1416
1423
  const watched = isWatched(name, _names, isBlurEvent);
1424
+ set(_formValues, name, fieldValue);
1417
1425
  if (isBlurEvent) {
1418
1426
  field._f.onBlur && field._f.onBlur(event);
1419
1427
  }
1420
1428
  else if (field._f.onChange) {
1421
1429
  field._f.onChange(event);
1422
1430
  }
1423
- set(_formValues, name, fieldValue);
1424
1431
  const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
1425
1432
  const shouldRender = !isEmptyObject(fieldState) || watched;
1426
1433
  !isBlurEvent &&
@@ -1501,7 +1508,6 @@ function createFormControl(props = {}) {
1501
1508
  : (_formState.errors = {});
1502
1509
  _subjects.state.next({
1503
1510
  errors: _formState.errors,
1504
- isValid: true,
1505
1511
  });
1506
1512
  };
1507
1513
  const setError = (name, error, options) => {
@@ -1542,20 +1548,18 @@ function createFormControl(props = {}) {
1542
1548
  };
1543
1549
  const register = (name, options = {}) => {
1544
1550
  let field = get(_fields, name);
1551
+ const disabledIsDefined = isBoolean(options.disabled);
1545
1552
  set(_fields, name, {
1546
1553
  _f: Object.assign(Object.assign(Object.assign({}, (field && field._f ? field._f : { ref: { name } })), { name, mount: true }), options),
1547
1554
  });
1548
1555
  _names.mount.add(name);
1549
- !isUndefined(options.value) &&
1550
- !options.disabled &&
1551
- set(_formValues, name, get(_formValues, name, options.value));
1552
1556
  field
1553
- ? isBoolean(options.disabled) &&
1557
+ ? disabledIsDefined &&
1554
1558
  set(_formValues, name, options.disabled
1555
1559
  ? undefined
1556
1560
  : get(_formValues, name, getFieldValue(field._f)))
1557
- : updateValidAndValue(name, true);
1558
- return Object.assign(Object.assign(Object.assign({}, (isBoolean(options.disabled) ? { disabled: options.disabled } : {})), (_options.shouldUseNativeValidation
1561
+ : updateValidAndValue(name, true, options.value);
1562
+ return Object.assign(Object.assign(Object.assign({}, (disabledIsDefined ? { disabled: options.disabled } : {})), (_options.shouldUseNativeValidation
1559
1563
  ? {
1560
1564
  required: !!options.required,
1561
1565
  min: getRuleValue(options.min),
@@ -1575,16 +1579,21 @@ function createFormControl(props = {}) {
1575
1579
  : ref
1576
1580
  : ref;
1577
1581
  const radioOrCheckbox = isRadioOrCheckbox(fieldRef);
1578
- if (fieldRef === field._f.ref ||
1579
- (radioOrCheckbox &&
1580
- compact(field._f.refs).find((option) => option === fieldRef))) {
1582
+ const refs = field._f.refs || [];
1583
+ if (radioOrCheckbox
1584
+ ? refs.find((option) => option === fieldRef)
1585
+ : fieldRef === field._f.ref) {
1581
1586
  return;
1582
1587
  }
1583
1588
  set(_fields, name, {
1584
- _f: radioOrCheckbox
1585
- ? Object.assign(Object.assign({}, field._f), { refs: [...compact(field._f.refs).filter(live), fieldRef], ref: { type: fieldRef.type, name } }) : Object.assign(Object.assign({}, field._f), { ref: fieldRef }),
1589
+ _f: Object.assign(Object.assign({}, field._f), (radioOrCheckbox
1590
+ ? {
1591
+ refs: refs.concat(fieldRef).filter(live),
1592
+ ref: { type: fieldRef.type, name },
1593
+ }
1594
+ : { ref: fieldRef })),
1586
1595
  });
1587
- updateValidAndValue(name, false, fieldRef);
1596
+ updateValidAndValue(name, false, undefined, fieldRef);
1588
1597
  }
1589
1598
  else {
1590
1599
  field = get(_fields, name, {});
@@ -1648,27 +1657,29 @@ function createFormControl(props = {}) {
1648
1657
  }
1649
1658
  };
1650
1659
  const resetField = (name, options = {}) => {
1651
- if (isUndefined(options.defaultValue)) {
1652
- setValue(name, get(_defaultValues, name));
1653
- }
1654
- else {
1655
- setValue(name, options.defaultValue);
1656
- set(_defaultValues, name, options.defaultValue);
1657
- }
1658
- if (!options.keepTouched) {
1659
- unset(_formState.touchedFields, name);
1660
- }
1661
- if (!options.keepDirty) {
1662
- unset(_formState.dirtyFields, name);
1663
- _formState.isDirty = options.defaultValue
1664
- ? _getDirty(name, get(_defaultValues, name))
1665
- : _getDirty();
1666
- }
1667
- if (!options.keepError) {
1668
- unset(_formState.errors, name);
1669
- _proxyFormState.isValid && _updateValid();
1660
+ if (get(_fields, name)) {
1661
+ if (isUndefined(options.defaultValue)) {
1662
+ setValue(name, get(_defaultValues, name));
1663
+ }
1664
+ else {
1665
+ setValue(name, options.defaultValue);
1666
+ set(_defaultValues, name, options.defaultValue);
1667
+ }
1668
+ if (!options.keepTouched) {
1669
+ unset(_formState.touchedFields, name);
1670
+ }
1671
+ if (!options.keepDirty) {
1672
+ unset(_formState.dirtyFields, name);
1673
+ _formState.isDirty = options.defaultValue
1674
+ ? _getDirty(name, get(_defaultValues, name))
1675
+ : _getDirty();
1676
+ }
1677
+ if (!options.keepError) {
1678
+ unset(_formState.errors, name);
1679
+ _proxyFormState.isValid && _updateValid();
1680
+ }
1681
+ _subjects.state.next(Object.assign({}, _formState));
1670
1682
  }
1671
- _subjects.state.next(Object.assign({}, _formState));
1672
1683
  };
1673
1684
  const reset = (formValues, keepStateOptions = {}) => {
1674
1685
  const updatedValues = formValues || _defaultValues;
@@ -1843,14 +1854,15 @@ function useForm(props = {}) {
1843
1854
  _formControl.current = Object.assign(Object.assign({}, createFormControl(props)), { formState });
1844
1855
  }
1845
1856
  const control = _formControl.current.control;
1857
+ const callback = React.useCallback((value) => {
1858
+ if (shouldRenderFormState(value, control._proxyFormState, true)) {
1859
+ control._formState = Object.assign(Object.assign({}, control._formState), value);
1860
+ updateFormState(Object.assign({}, control._formState));
1861
+ }
1862
+ }, [control]);
1846
1863
  useSubscribe({
1847
1864
  subject: control._subjects.state,
1848
- callback: (value) => {
1849
- if (shouldRenderFormState(value, control._proxyFormState, true)) {
1850
- control._formState = Object.assign(Object.assign({}, control._formState), value);
1851
- updateFormState(Object.assign({}, control._formState));
1852
- }
1853
- },
1865
+ callback,
1854
1866
  });
1855
1867
  React.useEffect(() => {
1856
1868
  if (!control._stateFlags.mount) {