react-hook-form 7.75.0 → 7.76.1

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.
@@ -489,7 +489,7 @@ function useController(props) {
489
489
  };
490
490
  updateMounted(name, true);
491
491
  if (_shouldUnregisterField) {
492
- const value = cloneObject(get(control._options.defaultValues, name, _props.current.defaultValue));
492
+ const value = cloneObject(get(control._defaultValues, name, get(control._options.defaultValues, name, _props.current.defaultValue)));
493
493
  set(control._defaultValues, name, value);
494
494
  if (isUndefined(get(control._formValues, name))) {
495
495
  set(control._formValues, name, value);
@@ -1266,8 +1266,7 @@ var validateField = async (field, disabledFieldNames, formValues, validateAllFie
1266
1266
  isUndefined(inputValue)) ||
1267
1267
  (isHTMLElement(ref) && ref.value === '') ||
1268
1268
  inputValue === '' ||
1269
- (Array.isArray(inputValue) && !inputValue.length) ||
1270
- (valueAsNumber && typeof inputValue === 'number' && isNaN(inputValue));
1269
+ (Array.isArray(inputValue) && !inputValue.length);
1271
1270
  const appendErrorsCurry = appendErrors.bind(null, name, validateAllFieldCriteria, error);
1272
1271
  const getMinMaxMessage = (exceedMax, maxLengthMessage, minLengthMessage, maxType = INPUT_VALIDATION_RULES.maxLength, minType = INPUT_VALIDATION_RULES.minLength) => {
1273
1272
  const message = exceedMax ? maxLengthMessage : minLengthMessage;
@@ -1597,9 +1596,28 @@ function createFormControl(props = {}) {
1597
1596
  isValid: false,
1598
1597
  });
1599
1598
  };
1599
+ const hasExplicitNullIntermediate = (name) => {
1600
+ const segments = isKey(name) ? [name] : stringToPath(name);
1601
+ let formValues = _formValues;
1602
+ let defaultValues = _defaultValues;
1603
+ for (let i = 0; i < segments.length - 1; i++) {
1604
+ const key = segments[i];
1605
+ formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
1606
+ defaultValues = isNullOrUndefined(defaultValues)
1607
+ ? defaultValues
1608
+ : defaultValues[key];
1609
+ if (formValues === null && defaultValues !== null) {
1610
+ return true;
1611
+ }
1612
+ }
1613
+ return false;
1614
+ };
1600
1615
  const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
1601
1616
  const field = get(_fields, name);
1602
1617
  if (field) {
1618
+ if (hasExplicitNullIntermediate(name)) {
1619
+ return;
1620
+ }
1603
1621
  const wasUnsetInFormValues = isUndefined(get(_formValues, name));
1604
1622
  const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
1605
1623
  isUndefined(defaultValue) ||
@@ -1642,9 +1660,14 @@ function createFormControl(props = {}) {
1642
1660
  }
1643
1661
  const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1644
1662
  isPreviousDirty = !!get(_formState.dirtyFields, name);
1645
- isCurrentFieldPristine
1646
- ? unset(_formState.dirtyFields, name)
1647
- : set(_formState.dirtyFields, name, true);
1663
+ if (isCurrentFieldPristine !== _formState.isDirty) {
1664
+ _formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
1665
+ }
1666
+ else {
1667
+ isCurrentFieldPristine
1668
+ ? unset(_formState.dirtyFields, name)
1669
+ : set(_formState.dirtyFields, name, true);
1670
+ }
1648
1671
  output.dirtyFields = _formState.dirtyFields;
1649
1672
  shouldUpdateField =
1650
1673
  shouldUpdateField ||
@@ -1711,7 +1734,9 @@ function createFormControl(props = {}) {
1711
1734
  for (const name of names) {
1712
1735
  const error = get(errors, name);
1713
1736
  error
1714
- ? set(_formState.errors, name, error)
1737
+ ? _names.array.has(name) && isObject(error)
1738
+ ? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
1739
+ : set(_formState.errors, name, error)
1715
1740
  : unset(_formState.errors, name);
1716
1741
  }
1717
1742
  }
@@ -1733,8 +1758,8 @@ function createFormControl(props = {}) {
1733
1758
  const error = result[key];
1734
1759
  if (error) {
1735
1760
  setError(`${FORM_ERROR_TYPE}.${key}`, {
1736
- message: isString(result.message) ? result.message : '',
1737
- type: INPUT_VALIDATION_RULES.validate,
1761
+ message: isString(error.message) ? error.message : '',
1762
+ type: error.type || INPUT_VALIDATION_RULES.validate,
1738
1763
  });
1739
1764
  }
1740
1765
  }
@@ -1776,11 +1801,15 @@ function createFormControl(props = {}) {
1776
1801
  if (_f) {
1777
1802
  const isFieldArrayRoot = _names.array.has(_f.name);
1778
1803
  const isPromiseFunction = field._f && hasPromiseValidation(field._f);
1779
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1804
+ const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
1805
+ _proxyFormState.isValidating ||
1806
+ _proxySubscribeFormState.validatingFields ||
1807
+ _proxySubscribeFormState.isValidating;
1808
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1780
1809
  _updateIsValidating([_f.name], true);
1781
1810
  }
1782
1811
  const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
1783
- if (isPromiseFunction && _proxyFormState.validatingFields) {
1812
+ if (isPromiseFunction && shouldTrackIsValidatingState) {
1784
1813
  _updateIsValidating([_f.name]);
1785
1814
  }
1786
1815
  if (fieldError[_f.name]) {
@@ -1835,7 +1864,7 @@ function createFormControl(props = {}) {
1835
1864
  : defaultValue),
1836
1865
  }, isGlobal, defaultValue);
1837
1866
  const _getFieldArray = (name) => compact(get(_state.mount ? _formValues : _defaultValues, name, _options.shouldUnregister ? get(_defaultValues, name, []) : []));
1838
- const setFieldValue = (name, value, options = {}) => {
1867
+ const setFieldValue = (name, value, options = {}, skipClone = false) => {
1839
1868
  const field = get(_fields, name);
1840
1869
  let fieldValue = value;
1841
1870
  if (field) {
@@ -1876,7 +1905,7 @@ function createFormControl(props = {}) {
1876
1905
  if (!fieldReference.ref.type) {
1877
1906
  _subjects.state.next({
1878
1907
  name,
1879
- values: cloneObject(_formValues),
1908
+ values: skipClone ? _formValues : cloneObject(_formValues),
1880
1909
  });
1881
1910
  }
1882
1911
  }
@@ -1886,7 +1915,7 @@ function createFormControl(props = {}) {
1886
1915
  updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1887
1916
  options.shouldValidate && trigger(name);
1888
1917
  };
1889
- const setFieldValues = (name, value, options) => {
1918
+ const setFieldValues = (name, value, options, skipClone = false) => {
1890
1919
  for (const fieldKey in value) {
1891
1920
  if (!value.hasOwnProperty(fieldKey)) {
1892
1921
  return;
@@ -1898,21 +1927,23 @@ function createFormControl(props = {}) {
1898
1927
  isObject(fieldValue) ||
1899
1928
  (field && !field._f)) &&
1900
1929
  !isDateObject(fieldValue)
1901
- ? setFieldValues(fieldName, fieldValue, options)
1902
- : setFieldValue(fieldName, fieldValue, options);
1930
+ ? setFieldValues(fieldName, fieldValue, options, skipClone)
1931
+ : setFieldValue(fieldName, fieldValue, options, skipClone);
1903
1932
  }
1904
1933
  };
1905
- const setValue = (name, value, options = {}) => {
1934
+ const _setValue = (name, value, options, skipClone) => {
1906
1935
  const field = get(_fields, name);
1907
1936
  const isFieldArray = _names.array.has(name);
1908
- const cloneValue = cloneObject(value);
1937
+ const cloneValue = skipClone ? value : cloneObject(value);
1909
1938
  const previousValue = get(_formValues, name);
1910
1939
  const isValueUnchanged = deepEqual(previousValue, cloneValue);
1911
- set(_formValues, name, cloneValue);
1940
+ if (!isValueUnchanged) {
1941
+ set(_formValues, name, cloneValue);
1942
+ }
1912
1943
  if (isFieldArray) {
1913
1944
  _subjects.array.next({
1914
1945
  name,
1915
- values: cloneObject(_formValues),
1946
+ values: skipClone ? _formValues : cloneObject(_formValues),
1916
1947
  });
1917
1948
  if ((_proxyFormState.isDirty ||
1918
1949
  _proxyFormState.dirtyFields ||
@@ -1931,22 +1962,24 @@ function createFormControl(props = {}) {
1931
1962
  const isEmpty = (Array.isArray(cloneValue) && !cloneValue.length) ||
1932
1963
  isEmptyObject(cloneValue);
1933
1964
  if (!field || field._f || isNullOrUndefined(cloneValue) || isEmpty) {
1934
- setFieldValue(name, cloneValue, options);
1965
+ setFieldValue(name, cloneValue, options, skipClone);
1935
1966
  }
1936
1967
  else {
1937
- setFieldValues(name, cloneValue, options);
1968
+ setFieldValues(name, cloneValue, options, skipClone);
1938
1969
  }
1939
1970
  }
1940
1971
  if (!isValueUnchanged) {
1941
1972
  const watched = isWatched(name, _names);
1973
+ const values = skipClone ? _formValues : cloneObject(_formValues);
1942
1974
  _subjects.state.next({
1943
1975
  ...(watched && _formState),
1944
1976
  name: _state.mount || watched ? name : undefined,
1945
- values: cloneObject(_formValues),
1977
+ values,
1946
1978
  });
1947
1979
  }
1948
1980
  };
1949
- const setValues = (formValues) => {
1981
+ const setValue = (name, value, options = {}) => _setValue(name, value, options, false);
1982
+ const setValues = (formValues, options = {}) => {
1950
1983
  const updatedFormValues = isFunction(formValues)
1951
1984
  ? formValues(_formValues)
1952
1985
  : formValues;
@@ -1955,7 +1988,18 @@ function createFormControl(props = {}) {
1955
1988
  ..._formValues,
1956
1989
  ...updatedFormValues,
1957
1990
  };
1958
- _subjects.state.next({ ..._formState, values: _formValues });
1991
+ for (const fieldName of _names.mount) {
1992
+ _setValue(fieldName, get(updatedFormValues, fieldName), options, true);
1993
+ }
1994
+ _subjects.state.next({
1995
+ ..._formState,
1996
+ name: undefined,
1997
+ type: undefined,
1998
+ values: _formValues,
1999
+ });
2000
+ if (options.shouldValidate) {
2001
+ _setValid();
2002
+ }
1959
2003
  }
1960
2004
  };
1961
2005
  const onChange = async (event) => {
@@ -2332,6 +2376,7 @@ function createFormControl(props = {}) {
2332
2376
  };
2333
2377
  };
2334
2378
  const _focusError = () => _options.shouldFocusError &&
2379
+ !_options.shouldUseNativeValidation &&
2335
2380
  iterateFieldsByAction(_fields, _focusInput, _names.mount);
2336
2381
  const _disableForm = (disabled) => {
2337
2382
  if (isBoolean(disabled)) {
@@ -3050,7 +3095,10 @@ function useForm(props = {}) {
3050
3095
  useIsomorphicLayoutEffect(() => {
3051
3096
  const sub = control._subscribe({
3052
3097
  formState: control._proxyFormState,
3053
- callback: () => updateFormState({ ...control._formState }),
3098
+ callback: () => updateFormState({
3099
+ ...control._formState,
3100
+ defaultValues: control._defaultValues,
3101
+ }),
3054
3102
  reRenderRoot: true,
3055
3103
  });
3056
3104
  updateFormState((data) => ({