react-hook-form 7.74.0 → 7.76.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/README.md +13 -9
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +164 -72
- package/dist/index.esm.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/logic/createFormControl.d.ts +13 -0
- package/dist/logic/createFormControl.d.ts.map +1 -1
- package/dist/logic/getDirtyFields.d.ts.map +1 -1
- package/dist/logic/{isNameInFieldArray.d.ts → getFieldArrayParentNames.d.ts} +2 -2
- package/dist/logic/getFieldArrayParentNames.d.ts.map +1 -0
- package/dist/logic/getProxyFormState.d.ts.map +1 -1
- package/dist/logic/getResolverOptions.d.ts +2 -2
- package/dist/logic/hasValidation.d.ts +1 -1
- package/dist/logic/shouldRenderFormState.d.ts.map +1 -1
- package/dist/react-server.esm.mjs +136 -49
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/form.d.ts +3 -2
- package/dist/types/form.d.ts.map +1 -1
- package/dist/types/utils.d.ts +2 -2
- package/dist/useController.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormContext.d.ts.map +1 -1
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/watch.d.ts +1 -1
- package/dist/watch.d.ts.map +1 -1
- package/package.json +4 -5
- package/dist/logic/isNameInFieldArray.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
|
@@ -18,9 +18,15 @@ var getEventValue = (event) => isObject(event) && event.target
|
|
|
18
18
|
: event.target.value
|
|
19
19
|
: event;
|
|
20
20
|
|
|
21
|
-
var
|
|
22
|
-
.split('.')
|
|
23
|
-
|
|
21
|
+
var getFieldArrayParentNames = (names, name) => {
|
|
22
|
+
const parts = name.split('.');
|
|
23
|
+
const matches = [];
|
|
24
|
+
let prefix = parts[0];
|
|
25
|
+
for (let i = 1; i < parts.length; prefix += '.' + parts[i++]) {
|
|
26
|
+
!isNaN(+parts[i]) && names.has(prefix) && matches.push(prefix);
|
|
27
|
+
}
|
|
28
|
+
return matches;
|
|
29
|
+
};
|
|
24
30
|
|
|
25
31
|
var isPlainObject = (tempObject) => {
|
|
26
32
|
const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype;
|
|
@@ -143,9 +149,7 @@ HookFormControlContext.displayName = 'HookFormControlContext';
|
|
|
143
149
|
const useFormControlContext = () => React.useContext(HookFormControlContext);
|
|
144
150
|
|
|
145
151
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
|
146
|
-
const result = {
|
|
147
|
-
defaultValues: control._defaultValues,
|
|
148
|
-
};
|
|
152
|
+
const result = {};
|
|
149
153
|
for (const key in formState) {
|
|
150
154
|
Object.defineProperty(result, key, {
|
|
151
155
|
get: () => {
|
|
@@ -196,7 +200,10 @@ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayou
|
|
|
196
200
|
function useFormState(props) {
|
|
197
201
|
const formControl = useFormControlContext();
|
|
198
202
|
const { control = formControl, disabled, name, exact } = props || {};
|
|
199
|
-
const [formState, updateFormState] = React.useState(
|
|
203
|
+
const [formState, updateFormState] = React.useState(() => ({
|
|
204
|
+
...control._formState,
|
|
205
|
+
defaultValues: control._defaultValues,
|
|
206
|
+
}));
|
|
200
207
|
const _localProxyFormState = React.useRef({
|
|
201
208
|
isDirty: false,
|
|
202
209
|
isLoading: false,
|
|
@@ -216,6 +223,7 @@ function useFormState(props) {
|
|
|
216
223
|
updateFormState({
|
|
217
224
|
...control._formState,
|
|
218
225
|
...formState,
|
|
226
|
+
defaultValues: control._defaultValues,
|
|
219
227
|
});
|
|
220
228
|
},
|
|
221
229
|
}), [name, disabled, exact]);
|
|
@@ -394,7 +402,8 @@ function useWatch(props) {
|
|
|
394
402
|
function useController(props) {
|
|
395
403
|
const formControl = useFormControlContext();
|
|
396
404
|
const { name, disabled, control = formControl, shouldUnregister, defaultValue, exact = true, } = props;
|
|
397
|
-
const isArrayField =
|
|
405
|
+
const isArrayField = !!getFieldArrayParentNames(control._names.array, name)
|
|
406
|
+
.length;
|
|
398
407
|
const defaultValueMemo = React.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
|
399
408
|
const value = useWatch({
|
|
400
409
|
control,
|
|
@@ -487,7 +496,7 @@ function useController(props) {
|
|
|
487
496
|
};
|
|
488
497
|
updateMounted(name, true);
|
|
489
498
|
if (_shouldUnregisterField) {
|
|
490
|
-
const value = cloneObject(get(control._options.defaultValues, name, _props.current.defaultValue));
|
|
499
|
+
const value = cloneObject(get(control._defaultValues, name, get(control._options.defaultValues, name, _props.current.defaultValue)));
|
|
491
500
|
set(control._defaultValues, name, value);
|
|
492
501
|
if (isUndefined(get(control._formValues, name))) {
|
|
493
502
|
set(control._formValues, name, value);
|
|
@@ -639,7 +648,7 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
|
639
648
|
* ```
|
|
640
649
|
*/
|
|
641
650
|
const FormProvider = (props) => {
|
|
642
|
-
const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
|
|
651
|
+
const { children, watch, getValues, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, handleSubmit, unregister, control, register, setFocus, subscribe, } = props;
|
|
643
652
|
const memoizedValue = React.useMemo(() => ({
|
|
644
653
|
watch,
|
|
645
654
|
getValues,
|
|
@@ -647,6 +656,7 @@ const FormProvider = (props) => {
|
|
|
647
656
|
setError,
|
|
648
657
|
clearErrors,
|
|
649
658
|
setValue,
|
|
659
|
+
setValues,
|
|
650
660
|
trigger,
|
|
651
661
|
formState,
|
|
652
662
|
resetField,
|
|
@@ -670,6 +680,7 @@ const FormProvider = (props) => {
|
|
|
670
680
|
setError,
|
|
671
681
|
setFocus,
|
|
672
682
|
setValue,
|
|
683
|
+
setValues,
|
|
673
684
|
subscribe,
|
|
674
685
|
trigger,
|
|
675
686
|
unregister,
|
|
@@ -943,6 +954,29 @@ function markFieldsDirty(data, fields = {}) {
|
|
|
943
954
|
}
|
|
944
955
|
return fields;
|
|
945
956
|
}
|
|
957
|
+
function pruneDirtyFields(value) {
|
|
958
|
+
if (value === false) {
|
|
959
|
+
return undefined;
|
|
960
|
+
}
|
|
961
|
+
if (value === true) {
|
|
962
|
+
return true;
|
|
963
|
+
}
|
|
964
|
+
if (Array.isArray(value)) {
|
|
965
|
+
const result = value.map((value) => pruneDirtyFields(value));
|
|
966
|
+
return (result.some((value) => value !== undefined) ? result : undefined);
|
|
967
|
+
}
|
|
968
|
+
if (isObject(value)) {
|
|
969
|
+
const result = {};
|
|
970
|
+
for (const key in value) {
|
|
971
|
+
const pruned = pruneDirtyFields(value[key]);
|
|
972
|
+
if (!isUndefined(pruned)) {
|
|
973
|
+
result[key] = pruned;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return (Object.keys(result).length ? result : undefined);
|
|
977
|
+
}
|
|
978
|
+
return undefined;
|
|
979
|
+
}
|
|
946
980
|
function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
947
981
|
if (!dirtyFieldsFromValues) {
|
|
948
982
|
dirtyFieldsFromValues = markFieldsDirty(formValues);
|
|
@@ -962,7 +996,7 @@ function getDirtyFields(data, formValues, dirtyFieldsFromValues) {
|
|
|
962
996
|
dirtyFieldsFromValues[key] = !deepEqual(value, formValue);
|
|
963
997
|
}
|
|
964
998
|
}
|
|
965
|
-
return dirtyFieldsFromValues;
|
|
999
|
+
return pruneDirtyFields(dirtyFieldsFromValues) || {};
|
|
966
1000
|
}
|
|
967
1001
|
|
|
968
1002
|
const defaultResult = {
|
|
@@ -1034,8 +1068,6 @@ function getFieldValue(_f) {
|
|
|
1034
1068
|
return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f);
|
|
1035
1069
|
}
|
|
1036
1070
|
|
|
1037
|
-
var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name;
|
|
1038
|
-
|
|
1039
1071
|
var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => {
|
|
1040
1072
|
const fields = {};
|
|
1041
1073
|
for (const name of fieldsNames) {
|
|
@@ -1160,7 +1192,8 @@ var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, is
|
|
|
1160
1192
|
updateFormState(formStateData);
|
|
1161
1193
|
const { name, ...formState } = formStateData;
|
|
1162
1194
|
return (isEmptyObject(formState) ||
|
|
1163
|
-
|
|
1195
|
+
(isRoot &&
|
|
1196
|
+
Object.keys(formState).length >= Object.keys(_proxyFormState).length) ||
|
|
1164
1197
|
Object.keys(formState).find((key) => _proxyFormState[key] ===
|
|
1165
1198
|
(!isRoot || VALIDATION_MODE.all)));
|
|
1166
1199
|
};
|
|
@@ -1403,24 +1436,27 @@ const defaultOptions = {
|
|
|
1403
1436
|
reValidateMode: VALIDATION_MODE.onChange,
|
|
1404
1437
|
shouldFocusError: true,
|
|
1405
1438
|
};
|
|
1439
|
+
const DEFAULT_FORM_STATE = {
|
|
1440
|
+
submitCount: 0,
|
|
1441
|
+
isDirty: false,
|
|
1442
|
+
isReady: false,
|
|
1443
|
+
isValidating: false,
|
|
1444
|
+
isSubmitted: false,
|
|
1445
|
+
isSubmitting: false,
|
|
1446
|
+
isSubmitSuccessful: false,
|
|
1447
|
+
isValid: false,
|
|
1448
|
+
touchedFields: {},
|
|
1449
|
+
dirtyFields: {},
|
|
1450
|
+
validatingFields: {},
|
|
1451
|
+
};
|
|
1406
1452
|
function createFormControl(props = {}) {
|
|
1407
1453
|
let _options = {
|
|
1408
1454
|
...defaultOptions,
|
|
1409
1455
|
...props,
|
|
1410
1456
|
};
|
|
1411
1457
|
let _formState = {
|
|
1412
|
-
|
|
1413
|
-
isDirty: false,
|
|
1414
|
-
isReady: false,
|
|
1458
|
+
...cloneObject(DEFAULT_FORM_STATE),
|
|
1415
1459
|
isLoading: isFunction(_options.defaultValues),
|
|
1416
|
-
isValidating: false,
|
|
1417
|
-
isSubmitted: false,
|
|
1418
|
-
isSubmitting: false,
|
|
1419
|
-
isSubmitSuccessful: false,
|
|
1420
|
-
isValid: false,
|
|
1421
|
-
touchedFields: {},
|
|
1422
|
-
dirtyFields: {},
|
|
1423
|
-
validatingFields: {},
|
|
1424
1460
|
errors: _options.errors || {},
|
|
1425
1461
|
disabled: _options.disabled || false,
|
|
1426
1462
|
};
|
|
@@ -1517,10 +1553,8 @@ function createFormControl(props = {}) {
|
|
|
1517
1553
|
});
|
|
1518
1554
|
}
|
|
1519
1555
|
};
|
|
1520
|
-
const _updateDirtyFields = (
|
|
1521
|
-
|
|
1522
|
-
const rootName = getNodeParentName(name);
|
|
1523
|
-
set(_formState.dirtyFields, rootName, get(fullDirtyFields, rootName));
|
|
1556
|
+
const _updateDirtyFields = () => {
|
|
1557
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
1524
1558
|
};
|
|
1525
1559
|
const _setFieldArray = (name, values = [], method, args, shouldSetValues = true, shouldUpdateFieldsAndState = true) => {
|
|
1526
1560
|
if (args && method && !_options.disabled) {
|
|
@@ -1543,7 +1577,7 @@ function createFormControl(props = {}) {
|
|
|
1543
1577
|
shouldSetValues && set(_formState.touchedFields, name, touchedFields);
|
|
1544
1578
|
}
|
|
1545
1579
|
if (_proxyFormState.dirtyFields || _proxySubscribeFormState.dirtyFields) {
|
|
1546
|
-
_updateDirtyFields(
|
|
1580
|
+
_updateDirtyFields();
|
|
1547
1581
|
}
|
|
1548
1582
|
_subjects.state.next({
|
|
1549
1583
|
name,
|
|
@@ -1570,16 +1604,53 @@ function createFormControl(props = {}) {
|
|
|
1570
1604
|
isValid: false,
|
|
1571
1605
|
});
|
|
1572
1606
|
};
|
|
1607
|
+
const hasExplicitNullIntermediate = (name) => {
|
|
1608
|
+
const segments = isKey(name) ? [name] : stringToPath(name);
|
|
1609
|
+
let formValues = _formValues;
|
|
1610
|
+
let defaultValues = _defaultValues;
|
|
1611
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
1612
|
+
const key = segments[i];
|
|
1613
|
+
formValues = isNullOrUndefined(formValues) ? formValues : formValues[key];
|
|
1614
|
+
defaultValues = isNullOrUndefined(defaultValues)
|
|
1615
|
+
? defaultValues
|
|
1616
|
+
: defaultValues[key];
|
|
1617
|
+
if (formValues === null && defaultValues !== null) {
|
|
1618
|
+
return true;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
return false;
|
|
1622
|
+
};
|
|
1573
1623
|
const updateValidAndValue = (name, shouldSkipSetValueAs, value, ref) => {
|
|
1574
1624
|
const field = get(_fields, name);
|
|
1575
1625
|
if (field) {
|
|
1626
|
+
if (hasExplicitNullIntermediate(name)) {
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1629
|
+
const wasUnsetInFormValues = isUndefined(get(_formValues, name));
|
|
1576
1630
|
const defaultValue = get(_formValues, name, isUndefined(value) ? get(_defaultValues, name) : value);
|
|
1577
1631
|
isUndefined(defaultValue) ||
|
|
1578
1632
|
(ref && ref.defaultChecked) ||
|
|
1579
1633
|
shouldSkipSetValueAs
|
|
1580
1634
|
? set(_formValues, name, shouldSkipSetValueAs ? defaultValue : getFieldValue(field._f))
|
|
1581
1635
|
: setFieldValue(name, defaultValue);
|
|
1582
|
-
_state.mount && !_state.action
|
|
1636
|
+
if (_state.mount && !_state.action) {
|
|
1637
|
+
_setValid();
|
|
1638
|
+
// Re-registering a field after a prior unregister puts its key back
|
|
1639
|
+
// into _formValues, which can flip isDirty back to false (#13397).
|
|
1640
|
+
// Only run when we are currently dirty, otherwise an initial register
|
|
1641
|
+
// for a field with no defaultValue would flip isDirty to true. Reset
|
|
1642
|
+
// paths repopulate _formValues before re-register, so the key is
|
|
1643
|
+
// present then and this branch is skipped (preserves keepDirty).
|
|
1644
|
+
if (wasUnsetInFormValues &&
|
|
1645
|
+
_formState.isDirty &&
|
|
1646
|
+
(_proxyFormState.isDirty || _proxySubscribeFormState.isDirty)) {
|
|
1647
|
+
const isDirty = _getDirty();
|
|
1648
|
+
if (!isDirty) {
|
|
1649
|
+
_formState.isDirty = false;
|
|
1650
|
+
_subjects.state.next({ ..._formState });
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1583
1654
|
}
|
|
1584
1655
|
};
|
|
1585
1656
|
const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
|
|
@@ -1597,9 +1668,14 @@ function createFormControl(props = {}) {
|
|
|
1597
1668
|
}
|
|
1598
1669
|
const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
|
|
1599
1670
|
isPreviousDirty = !!get(_formState.dirtyFields, name);
|
|
1600
|
-
isCurrentFieldPristine
|
|
1601
|
-
|
|
1602
|
-
|
|
1671
|
+
if (isCurrentFieldPristine !== _formState.isDirty) {
|
|
1672
|
+
_formState.dirtyFields = getDirtyFields(_defaultValues, _formValues);
|
|
1673
|
+
}
|
|
1674
|
+
else {
|
|
1675
|
+
isCurrentFieldPristine
|
|
1676
|
+
? unset(_formState.dirtyFields, name)
|
|
1677
|
+
: set(_formState.dirtyFields, name, true);
|
|
1678
|
+
}
|
|
1603
1679
|
output.dirtyFields = _formState.dirtyFields;
|
|
1604
1680
|
shouldUpdateField =
|
|
1605
1681
|
shouldUpdateField ||
|
|
@@ -1666,7 +1742,9 @@ function createFormControl(props = {}) {
|
|
|
1666
1742
|
for (const name of names) {
|
|
1667
1743
|
const error = get(errors, name);
|
|
1668
1744
|
error
|
|
1669
|
-
?
|
|
1745
|
+
? _names.array.has(name) && isObject(error)
|
|
1746
|
+
? updateFieldArrayRootError(_formState.errors, { [name]: error }, name)
|
|
1747
|
+
: set(_formState.errors, name, error)
|
|
1670
1748
|
: unset(_formState.errors, name);
|
|
1671
1749
|
}
|
|
1672
1750
|
}
|
|
@@ -1688,8 +1766,8 @@ function createFormControl(props = {}) {
|
|
|
1688
1766
|
const error = result[key];
|
|
1689
1767
|
if (error) {
|
|
1690
1768
|
setError(`${FORM_ERROR_TYPE}.${key}`, {
|
|
1691
|
-
message: isString(
|
|
1692
|
-
type: INPUT_VALIDATION_RULES.validate,
|
|
1769
|
+
message: isString(error.message) ? error.message : '',
|
|
1770
|
+
type: error.type || INPUT_VALIDATION_RULES.validate,
|
|
1693
1771
|
});
|
|
1694
1772
|
}
|
|
1695
1773
|
}
|
|
@@ -1731,11 +1809,15 @@ function createFormControl(props = {}) {
|
|
|
1731
1809
|
if (_f) {
|
|
1732
1810
|
const isFieldArrayRoot = _names.array.has(_f.name);
|
|
1733
1811
|
const isPromiseFunction = field._f && hasPromiseValidation(field._f);
|
|
1734
|
-
|
|
1812
|
+
const shouldTrackIsValidatingState = _proxyFormState.validatingFields ||
|
|
1813
|
+
_proxyFormState.isValidating ||
|
|
1814
|
+
_proxySubscribeFormState.validatingFields ||
|
|
1815
|
+
_proxySubscribeFormState.isValidating;
|
|
1816
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1735
1817
|
_updateIsValidating([_f.name], true);
|
|
1736
1818
|
}
|
|
1737
1819
|
const fieldError = await validateField(field, _names.disabled, _formValues, shouldDisplayAllAssociatedErrors, _options.shouldUseNativeValidation && !onlyCheckValid, isFieldArrayRoot);
|
|
1738
|
-
if (isPromiseFunction &&
|
|
1820
|
+
if (isPromiseFunction && shouldTrackIsValidatingState) {
|
|
1739
1821
|
_updateIsValidating([_f.name]);
|
|
1740
1822
|
}
|
|
1741
1823
|
if (fieldError[_f.name]) {
|
|
@@ -1863,14 +1945,20 @@ function createFormControl(props = {}) {
|
|
|
1863
1945
|
const cloneValue = cloneObject(value);
|
|
1864
1946
|
const previousValue = get(_formValues, name);
|
|
1865
1947
|
const isValueUnchanged = deepEqual(previousValue, cloneValue);
|
|
1866
|
-
|
|
1948
|
+
if (!isValueUnchanged) {
|
|
1949
|
+
set(_formValues, name, cloneValue);
|
|
1950
|
+
}
|
|
1867
1951
|
if (isFieldArray) {
|
|
1868
1952
|
_subjects.array.next({
|
|
1869
1953
|
name,
|
|
1870
1954
|
values: cloneObject(_formValues),
|
|
1871
1955
|
});
|
|
1872
|
-
if (
|
|
1873
|
-
|
|
1956
|
+
if ((_proxyFormState.isDirty ||
|
|
1957
|
+
_proxyFormState.dirtyFields ||
|
|
1958
|
+
_proxySubscribeFormState.isDirty ||
|
|
1959
|
+
_proxySubscribeFormState.dirtyFields) &&
|
|
1960
|
+
options.shouldDirty) {
|
|
1961
|
+
_updateDirtyFields();
|
|
1874
1962
|
_subjects.state.next({
|
|
1875
1963
|
name,
|
|
1876
1964
|
dirtyFields: _formState.dirtyFields,
|
|
@@ -1889,19 +1977,18 @@ function createFormControl(props = {}) {
|
|
|
1889
1977
|
}
|
|
1890
1978
|
}
|
|
1891
1979
|
if (!isValueUnchanged) {
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
else {
|
|
1900
|
-
_subjects.state.next({
|
|
1901
|
-
name: _state.mount ? name : undefined,
|
|
1902
|
-
values: cloneObject(_formValues),
|
|
1903
|
-
});
|
|
1980
|
+
const watched = isWatched(name, _names);
|
|
1981
|
+
const values = cloneObject(_formValues);
|
|
1982
|
+
if (!isFieldArray) {
|
|
1983
|
+
for (const arrayName of getFieldArrayParentNames(_names.array, name)) {
|
|
1984
|
+
_subjects.array.next({ name: arrayName, values });
|
|
1985
|
+
}
|
|
1904
1986
|
}
|
|
1987
|
+
_subjects.state.next({
|
|
1988
|
+
...(watched && _formState),
|
|
1989
|
+
name: _state.mount || watched ? name : undefined,
|
|
1990
|
+
values,
|
|
1991
|
+
});
|
|
1905
1992
|
}
|
|
1906
1993
|
};
|
|
1907
1994
|
const setValues = (formValues) => {
|
|
@@ -1913,6 +2000,9 @@ function createFormControl(props = {}) {
|
|
|
1913
2000
|
..._formValues,
|
|
1914
2001
|
...updatedFormValues,
|
|
1915
2002
|
};
|
|
2003
|
+
for (const fieldName of _names.mount) {
|
|
2004
|
+
setValue(fieldName, get(updatedFormValues, fieldName));
|
|
2005
|
+
}
|
|
1916
2006
|
_subjects.state.next({ ..._formState, values: _formValues });
|
|
1917
2007
|
}
|
|
1918
2008
|
};
|
|
@@ -2283,13 +2373,15 @@ function createFormControl(props = {}) {
|
|
|
2283
2373
|
field._f.mount = false;
|
|
2284
2374
|
}
|
|
2285
2375
|
(_options.shouldUnregister || options.shouldUnregister) &&
|
|
2286
|
-
!(
|
|
2376
|
+
!(getFieldArrayParentNames(_names.array, name).length &&
|
|
2377
|
+
_state.action) &&
|
|
2287
2378
|
_names.unMount.add(name);
|
|
2288
2379
|
}
|
|
2289
2380
|
},
|
|
2290
2381
|
};
|
|
2291
2382
|
};
|
|
2292
2383
|
const _focusError = () => _options.shouldFocusError &&
|
|
2384
|
+
!_options.shouldUseNativeValidation &&
|
|
2293
2385
|
iterateFieldsByAction(_fields, _focusInput, _names.mount);
|
|
2294
2386
|
const _disableForm = (disabled) => {
|
|
2295
2387
|
if (isBoolean(disabled)) {
|
|
@@ -2910,15 +3002,22 @@ function useFieldArray(props) {
|
|
|
2910
3002
|
React.useEffect(() => {
|
|
2911
3003
|
!get(control._formValues, name) && control._setFieldArray(name);
|
|
2912
3004
|
return () => {
|
|
3005
|
+
const shouldKeepFieldArrayValues = !(control._options.shouldUnregister || shouldUnregister);
|
|
2913
3006
|
const updateMounted = (name, value) => {
|
|
2914
3007
|
const field = get(control._fields, name);
|
|
2915
3008
|
if (field && field._f) {
|
|
2916
3009
|
field._f.mount = value;
|
|
2917
3010
|
}
|
|
2918
3011
|
};
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
3012
|
+
if (_actioned.current && shouldKeepFieldArrayValues) {
|
|
3013
|
+
control._subjects.state.next({
|
|
3014
|
+
name,
|
|
3015
|
+
values: cloneObject(control._formValues),
|
|
3016
|
+
});
|
|
3017
|
+
}
|
|
3018
|
+
shouldKeepFieldArrayValues
|
|
3019
|
+
? updateMounted(name, false)
|
|
3020
|
+
: control.unregister(name);
|
|
2922
3021
|
};
|
|
2923
3022
|
}, [name, control, keyName, shouldUnregister]);
|
|
2924
3023
|
return {
|
|
@@ -2969,25 +3068,15 @@ function useFieldArray(props) {
|
|
|
2969
3068
|
function useForm(props = {}) {
|
|
2970
3069
|
const _formControl = React.useRef(undefined);
|
|
2971
3070
|
const _values = React.useRef(undefined);
|
|
2972
|
-
const [formState, updateFormState] = React.useState({
|
|
2973
|
-
|
|
2974
|
-
isValidating: false,
|
|
3071
|
+
const [formState, updateFormState] = React.useState(() => ({
|
|
3072
|
+
...cloneObject(DEFAULT_FORM_STATE),
|
|
2975
3073
|
isLoading: isFunction(props.defaultValues),
|
|
2976
|
-
isSubmitted: false,
|
|
2977
|
-
isSubmitting: false,
|
|
2978
|
-
isSubmitSuccessful: false,
|
|
2979
|
-
isValid: false,
|
|
2980
|
-
submitCount: 0,
|
|
2981
|
-
dirtyFields: {},
|
|
2982
|
-
touchedFields: {},
|
|
2983
|
-
validatingFields: {},
|
|
2984
3074
|
errors: props.errors || {},
|
|
2985
3075
|
disabled: props.disabled || false,
|
|
2986
|
-
isReady: false,
|
|
2987
3076
|
defaultValues: isFunction(props.defaultValues)
|
|
2988
3077
|
? undefined
|
|
2989
3078
|
: props.defaultValues,
|
|
2990
|
-
});
|
|
3079
|
+
}));
|
|
2991
3080
|
if (!_formControl.current) {
|
|
2992
3081
|
if (props.formControl) {
|
|
2993
3082
|
_formControl.current = {
|
|
@@ -3011,7 +3100,10 @@ function useForm(props = {}) {
|
|
|
3011
3100
|
useIsomorphicLayoutEffect(() => {
|
|
3012
3101
|
const sub = control._subscribe({
|
|
3013
3102
|
formState: control._proxyFormState,
|
|
3014
|
-
callback: () => updateFormState({
|
|
3103
|
+
callback: () => updateFormState({
|
|
3104
|
+
...control._formState,
|
|
3105
|
+
defaultValues: control._defaultValues,
|
|
3106
|
+
}),
|
|
3015
3107
|
reRenderRoot: true,
|
|
3016
3108
|
});
|
|
3017
3109
|
updateFormState((data) => ({
|