react-hook-form 7.60.0 → 7.61.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.
- package/README.md +1 -0
- package/dist/form.d.ts.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +126 -106
- 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.map +1 -1
- package/dist/react-server.esm.mjs +4 -2
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/types/form.d.ts +1 -0
- package/dist/types/form.d.ts.map +1 -1
- package/dist/useController.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useIsomorphicLayoutEffect.d.ts +1 -1
- package/dist/useIsomorphicLayoutEffect.d.ts.map +1 -1
- package/dist/useWatch.d.ts +99 -8
- package/dist/useWatch.d.ts.map +1 -1
- package/package.json +3 -4
- package/dist/__typetest__/__fixtures__/index.d.ts +0 -5
- package/dist/__typetest__/__fixtures__/index.d.ts.map +0 -1
- package/dist/__typetest__/__fixtures__/pathString.d.ts +0 -4
- package/dist/__typetest__/__fixtures__/pathString.d.ts.map +0 -1
- package/dist/__typetest__/__fixtures__/traversable.d.ts +0 -14
- package/dist/__typetest__/__fixtures__/traversable.d.ts.map +0 -1
- package/dist/__typetest__/__fixtures__/tuple.d.ts +0 -15
- package/dist/__typetest__/__fixtures__/tuple.d.ts.map +0 -1
- package/dist/__typetest__/__fixtures__/type.d.ts +0 -12
- package/dist/__typetest__/__fixtures__/type.d.ts.map +0 -1
- package/dist/__typetest__/errors.test-d.d.ts +0 -2
- package/dist/__typetest__/errors.test-d.d.ts.map +0 -1
- package/dist/__typetest__/form.test-d.d.ts +0 -11
- package/dist/__typetest__/form.test-d.d.ts.map +0 -1
- package/dist/__typetest__/path/common.test-d.d.ts +0 -2
- package/dist/__typetest__/path/common.test-d.d.ts.map +0 -1
- package/dist/__typetest__/path/eager.test-d.d.ts +0 -2
- package/dist/__typetest__/path/eager.test-d.d.ts.map +0 -1
- package/dist/__typetest__/use-form-context.test-d.d.ts +0 -2
- package/dist/__typetest__/use-form-context.test-d.d.ts.map +0 -1
- package/dist/__typetest__/util.test-d.d.ts +0 -2
- package/dist/__typetest__/util.test-d.d.ts.map +0 -1
- package/dist/utils/omit.d.ts +0 -3
- package/dist/utils/omit.d.ts.map +0 -1
package/dist/index.esm.mjs
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
import
|
2
|
-
import React__default from 'react';
|
1
|
+
import React from 'react';
|
3
2
|
|
4
3
|
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
5
4
|
|
@@ -128,7 +127,7 @@ const INPUT_VALIDATION_RULES = {
|
|
128
127
|
validate: 'validate',
|
129
128
|
};
|
130
129
|
|
131
|
-
const HookFormContext =
|
130
|
+
const HookFormContext = React.createContext(null);
|
132
131
|
HookFormContext.displayName = 'HookFormContext';
|
133
132
|
/**
|
134
133
|
* This custom hook allows you to access the form context. useFormContext is intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop. To be used with {@link FormProvider}.
|
@@ -160,7 +159,7 @@ HookFormContext.displayName = 'HookFormContext';
|
|
160
159
|
* }
|
161
160
|
* ```
|
162
161
|
*/
|
163
|
-
const useFormContext = () =>
|
162
|
+
const useFormContext = () => React.useContext(HookFormContext);
|
164
163
|
/**
|
165
164
|
* A provider component that propagates the `useForm` methods to all children components via [React Context](https://reactjs.org/docs/context.html) API. To be used with {@link useFormContext}.
|
166
165
|
*
|
@@ -193,7 +192,7 @@ const useFormContext = () => React__default.useContext(HookFormContext);
|
|
193
192
|
*/
|
194
193
|
const FormProvider = (props) => {
|
195
194
|
const { children, ...data } = props;
|
196
|
-
return (
|
195
|
+
return (React.createElement(HookFormContext.Provider, { value: data }, children));
|
197
196
|
};
|
198
197
|
|
199
198
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
@@ -250,8 +249,8 @@ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayou
|
|
250
249
|
function useFormState(props) {
|
251
250
|
const methods = useFormContext();
|
252
251
|
const { control = methods.control, disabled, name, exact } = props || {};
|
253
|
-
const [formState, updateFormState] =
|
254
|
-
const _localProxyFormState =
|
252
|
+
const [formState, updateFormState] = React.useState(control._formState);
|
253
|
+
const _localProxyFormState = React.useRef({
|
255
254
|
isDirty: false,
|
256
255
|
isLoading: false,
|
257
256
|
dirtyFields: false,
|
@@ -273,10 +272,10 @@ function useFormState(props) {
|
|
273
272
|
});
|
274
273
|
},
|
275
274
|
}), [name, disabled, exact]);
|
276
|
-
|
275
|
+
React.useEffect(() => {
|
277
276
|
_localProxyFormState.current.isValid && control._setValid(true);
|
278
277
|
}, [control]);
|
279
|
-
return
|
278
|
+
return React.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
|
280
279
|
}
|
281
280
|
|
282
281
|
var isString = (value) => typeof value === 'string';
|
@@ -294,6 +293,44 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
294
293
|
return formValues;
|
295
294
|
};
|
296
295
|
|
296
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
297
|
+
|
298
|
+
function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
299
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
300
|
+
return object1 === object2;
|
301
|
+
}
|
302
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
303
|
+
return object1.getTime() === object2.getTime();
|
304
|
+
}
|
305
|
+
const keys1 = Object.keys(object1);
|
306
|
+
const keys2 = Object.keys(object2);
|
307
|
+
if (keys1.length !== keys2.length) {
|
308
|
+
return false;
|
309
|
+
}
|
310
|
+
if (_internal_visited.has(object1) || _internal_visited.has(object2)) {
|
311
|
+
return true;
|
312
|
+
}
|
313
|
+
_internal_visited.add(object1);
|
314
|
+
_internal_visited.add(object2);
|
315
|
+
for (const key of keys1) {
|
316
|
+
const val1 = object1[key];
|
317
|
+
if (!keys2.includes(key)) {
|
318
|
+
return false;
|
319
|
+
}
|
320
|
+
if (key !== 'ref') {
|
321
|
+
const val2 = object2[key];
|
322
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
323
|
+
(isObject(val1) && isObject(val2)) ||
|
324
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
325
|
+
? !deepEqual(val1, val2, _internal_visited)
|
326
|
+
: val1 !== val2) {
|
327
|
+
return false;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
return true;
|
332
|
+
}
|
333
|
+
|
297
334
|
/**
|
298
335
|
* Custom hook to subscribe to field change and isolate re-rendering at the component level.
|
299
336
|
*
|
@@ -312,19 +349,36 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
312
349
|
*/
|
313
350
|
function useWatch(props) {
|
314
351
|
const methods = useFormContext();
|
315
|
-
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
316
|
-
const _defaultValue =
|
317
|
-
const
|
352
|
+
const { control = methods.control, name, defaultValue, disabled, exact, compute, } = props || {};
|
353
|
+
const _defaultValue = React.useRef(defaultValue);
|
354
|
+
const _compute = React.useRef(compute);
|
355
|
+
const _computeFormValues = React.useRef(undefined);
|
356
|
+
_compute.current = compute;
|
357
|
+
const defaultValueMemo = React.useMemo(() => control._getWatch(name, _defaultValue.current), [control, name]);
|
358
|
+
const [value, updateValue] = React.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo);
|
318
359
|
useIsomorphicLayoutEffect(() => control._subscribe({
|
319
360
|
name,
|
320
361
|
formState: {
|
321
362
|
values: true,
|
322
363
|
},
|
323
364
|
exact,
|
324
|
-
callback: (formState) =>
|
325
|
-
|
326
|
-
|
327
|
-
|
365
|
+
callback: (formState) => {
|
366
|
+
if (!disabled) {
|
367
|
+
const formValues = generateWatchOutput(name, control._names, formState.values || control._formValues, false, _defaultValue.current);
|
368
|
+
if (_compute.current) {
|
369
|
+
const computedFormValues = _compute.current(formValues);
|
370
|
+
if (!deepEqual(computedFormValues, _computeFormValues.current)) {
|
371
|
+
updateValue(computedFormValues);
|
372
|
+
_computeFormValues.current = computedFormValues;
|
373
|
+
}
|
374
|
+
}
|
375
|
+
else {
|
376
|
+
updateValue(formValues);
|
377
|
+
}
|
378
|
+
}
|
379
|
+
},
|
380
|
+
}), [control, disabled, name, exact]);
|
381
|
+
React.useEffect(() => control._removeUnmounted());
|
328
382
|
return value;
|
329
383
|
}
|
330
384
|
|
@@ -354,12 +408,13 @@ function useWatch(props) {
|
|
354
408
|
*/
|
355
409
|
function useController(props) {
|
356
410
|
const methods = useFormContext();
|
357
|
-
const { name, disabled, control = methods.control, shouldUnregister } = props;
|
411
|
+
const { name, disabled, control = methods.control, shouldUnregister, defaultValue, } = props;
|
358
412
|
const isArrayField = isNameInFieldArray(control._names.array, name);
|
413
|
+
const defaultValueMemo = React.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
359
414
|
const value = useWatch({
|
360
415
|
control,
|
361
416
|
name,
|
362
|
-
defaultValue:
|
417
|
+
defaultValue: defaultValueMemo,
|
363
418
|
exact: true,
|
364
419
|
});
|
365
420
|
const formState = useFormState({
|
@@ -367,13 +422,14 @@ function useController(props) {
|
|
367
422
|
name,
|
368
423
|
exact: true,
|
369
424
|
});
|
370
|
-
const _props =
|
371
|
-
const _registerProps =
|
425
|
+
const _props = React.useRef(props);
|
426
|
+
const _registerProps = React.useRef(control.register(name, {
|
372
427
|
...props.rules,
|
373
428
|
value,
|
374
429
|
...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
|
375
430
|
}));
|
376
|
-
|
431
|
+
_props.current = props;
|
432
|
+
const fieldState = React.useMemo(() => Object.defineProperties({}, {
|
377
433
|
invalid: {
|
378
434
|
enumerable: true,
|
379
435
|
get: () => !!get(formState.errors, name),
|
@@ -395,21 +451,21 @@ function useController(props) {
|
|
395
451
|
get: () => get(formState.errors, name),
|
396
452
|
},
|
397
453
|
}), [formState, name]);
|
398
|
-
const onChange =
|
454
|
+
const onChange = React.useCallback((event) => _registerProps.current.onChange({
|
399
455
|
target: {
|
400
456
|
value: getEventValue(event),
|
401
457
|
name: name,
|
402
458
|
},
|
403
459
|
type: EVENTS.CHANGE,
|
404
460
|
}), [name]);
|
405
|
-
const onBlur =
|
461
|
+
const onBlur = React.useCallback(() => _registerProps.current.onBlur({
|
406
462
|
target: {
|
407
463
|
value: get(control._formValues, name),
|
408
464
|
name: name,
|
409
465
|
},
|
410
466
|
type: EVENTS.BLUR,
|
411
467
|
}), [name, control._formValues]);
|
412
|
-
const ref =
|
468
|
+
const ref = React.useCallback((elm) => {
|
413
469
|
const field = get(control._fields, name);
|
414
470
|
if (field && elm) {
|
415
471
|
field._f.ref = {
|
@@ -420,7 +476,7 @@ function useController(props) {
|
|
420
476
|
};
|
421
477
|
}
|
422
478
|
}, [control._fields, name]);
|
423
|
-
const field =
|
479
|
+
const field = React.useMemo(() => ({
|
424
480
|
name,
|
425
481
|
value,
|
426
482
|
...(isBoolean(disabled) || formState.disabled
|
@@ -430,7 +486,7 @@ function useController(props) {
|
|
430
486
|
onBlur,
|
431
487
|
ref,
|
432
488
|
}), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
|
433
|
-
|
489
|
+
React.useEffect(() => {
|
434
490
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
435
491
|
control.register(name, {
|
436
492
|
..._props.current.rules,
|
@@ -461,13 +517,13 @@ function useController(props) {
|
|
461
517
|
: updateMounted(name, false);
|
462
518
|
};
|
463
519
|
}, [name, control, isArrayField, shouldUnregister]);
|
464
|
-
|
520
|
+
React.useEffect(() => {
|
465
521
|
control._setDisabledField({
|
466
522
|
disabled,
|
467
523
|
name,
|
468
524
|
});
|
469
525
|
}, [disabled, name, control]);
|
470
|
-
return
|
526
|
+
return React.useMemo(() => ({
|
471
527
|
field,
|
472
528
|
formState,
|
473
529
|
fieldState,
|
@@ -559,7 +615,7 @@ const POST_REQUEST = 'post';
|
|
559
615
|
*/
|
560
616
|
function Form(props) {
|
561
617
|
const methods = useFormContext();
|
562
|
-
const [mounted, setMounted] =
|
618
|
+
const [mounted, setMounted] = React.useState(false);
|
563
619
|
const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, ...rest } = props;
|
564
620
|
const submit = async (event) => {
|
565
621
|
let hasError = false;
|
@@ -594,7 +650,9 @@ function Form(props) {
|
|
594
650
|
method,
|
595
651
|
headers: {
|
596
652
|
...headers,
|
597
|
-
...(encType
|
653
|
+
...(encType && encType !== 'multipart/form-data'
|
654
|
+
? { 'Content-Type': encType }
|
655
|
+
: {}),
|
598
656
|
},
|
599
657
|
body: shouldStringifySubmissionData ? formDataJson : formData,
|
600
658
|
});
|
@@ -625,12 +683,12 @@ function Form(props) {
|
|
625
683
|
});
|
626
684
|
}
|
627
685
|
};
|
628
|
-
|
686
|
+
React.useEffect(() => {
|
629
687
|
setMounted(true);
|
630
688
|
}, []);
|
631
|
-
return render ? (
|
689
|
+
return render ? (React.createElement(React.Fragment, null, render({
|
632
690
|
submit,
|
633
|
-
}))) : (
|
691
|
+
}))) : (React.createElement("form", { noValidate: mounted, action: action, method: method, encType: encType, onSubmit: submit, ...rest }, children));
|
634
692
|
}
|
635
693
|
|
636
694
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
@@ -673,44 +731,6 @@ var createSubject = () => {
|
|
673
731
|
};
|
674
732
|
};
|
675
733
|
|
676
|
-
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
677
|
-
|
678
|
-
function deepEqual(object1, object2, _internal_visited = new WeakSet()) {
|
679
|
-
if (isPrimitive(object1) || isPrimitive(object2)) {
|
680
|
-
return object1 === object2;
|
681
|
-
}
|
682
|
-
if (isDateObject(object1) && isDateObject(object2)) {
|
683
|
-
return object1.getTime() === object2.getTime();
|
684
|
-
}
|
685
|
-
const keys1 = Object.keys(object1);
|
686
|
-
const keys2 = Object.keys(object2);
|
687
|
-
if (keys1.length !== keys2.length) {
|
688
|
-
return false;
|
689
|
-
}
|
690
|
-
if (_internal_visited.has(object1) || _internal_visited.has(object2)) {
|
691
|
-
return true;
|
692
|
-
}
|
693
|
-
_internal_visited.add(object1);
|
694
|
-
_internal_visited.add(object2);
|
695
|
-
for (const key of keys1) {
|
696
|
-
const val1 = object1[key];
|
697
|
-
if (!keys2.includes(key)) {
|
698
|
-
return false;
|
699
|
-
}
|
700
|
-
if (key !== 'ref') {
|
701
|
-
const val2 = object2[key];
|
702
|
-
if ((isDateObject(val1) && isDateObject(val2)) ||
|
703
|
-
(isObject(val1) && isObject(val2)) ||
|
704
|
-
(Array.isArray(val1) && Array.isArray(val2))
|
705
|
-
? !deepEqual(val1, val2, _internal_visited)
|
706
|
-
: val1 !== val2) {
|
707
|
-
return false;
|
708
|
-
}
|
709
|
-
}
|
710
|
-
}
|
711
|
-
return true;
|
712
|
-
}
|
713
|
-
|
714
734
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
715
735
|
|
716
736
|
var isFileInput = (element) => element.type === 'file';
|
@@ -1662,7 +1682,7 @@ function createFormControl(props = {}) {
|
|
1662
1682
|
? setValues(name, cloneValue, options)
|
1663
1683
|
: setFieldValue(name, cloneValue, options);
|
1664
1684
|
}
|
1665
|
-
isWatched(name, _names) && _subjects.state.next({ ..._formState });
|
1685
|
+
isWatched(name, _names) && _subjects.state.next({ ..._formState, name });
|
1666
1686
|
_subjects.state.next({
|
1667
1687
|
name: _state.mount ? name : undefined,
|
1668
1688
|
values: cloneObject(_formValues),
|
@@ -1844,7 +1864,8 @@ function createFormControl(props = {}) {
|
|
1844
1864
|
};
|
1845
1865
|
const watch = (name, defaultValue) => isFunction(name)
|
1846
1866
|
? _subjects.state.subscribe({
|
1847
|
-
next: (payload) =>
|
1867
|
+
next: (payload) => 'values' in payload &&
|
1868
|
+
name(_getWatch(undefined, defaultValue), payload),
|
1848
1869
|
})
|
1849
1870
|
: _getWatch(name, defaultValue, true);
|
1850
1871
|
const _subscribe = (props) => _subjects.state.subscribe({
|
@@ -1855,6 +1876,7 @@ function createFormControl(props = {}) {
|
|
1855
1876
|
values: { ..._formValues },
|
1856
1877
|
..._formState,
|
1857
1878
|
...formState,
|
1879
|
+
defaultValues: _defaultValues,
|
1858
1880
|
});
|
1859
1881
|
}
|
1860
1882
|
},
|
@@ -2411,28 +2433,26 @@ var updateAt = (fieldValues, index, value) => {
|
|
2411
2433
|
function useFieldArray(props) {
|
2412
2434
|
const methods = useFormContext();
|
2413
2435
|
const { control = methods.control, name, keyName = 'id', shouldUnregister, rules, } = props;
|
2414
|
-
const [fields, setFields] =
|
2415
|
-
const ids =
|
2416
|
-
const _fieldIds =
|
2417
|
-
const
|
2418
|
-
const _actioned = React__default.useRef(false);
|
2419
|
-
_name.current = name;
|
2436
|
+
const [fields, setFields] = React.useState(control._getFieldArray(name));
|
2437
|
+
const ids = React.useRef(control._getFieldArray(name).map(generateId));
|
2438
|
+
const _fieldIds = React.useRef(fields);
|
2439
|
+
const _actioned = React.useRef(false);
|
2420
2440
|
_fieldIds.current = fields;
|
2421
2441
|
control._names.array.add(name);
|
2422
|
-
rules &&
|
2423
|
-
control.register(name, rules);
|
2442
|
+
React.useMemo(() => rules &&
|
2443
|
+
control.register(name, rules), [control, rules, name]);
|
2424
2444
|
useIsomorphicLayoutEffect(() => control._subjects.array.subscribe({
|
2425
2445
|
next: ({ values, name: fieldArrayName, }) => {
|
2426
|
-
if (fieldArrayName ===
|
2427
|
-
const fieldValues = get(values,
|
2446
|
+
if (fieldArrayName === name || !fieldArrayName) {
|
2447
|
+
const fieldValues = get(values, name);
|
2428
2448
|
if (Array.isArray(fieldValues)) {
|
2429
2449
|
setFields(fieldValues);
|
2430
2450
|
ids.current = fieldValues.map(generateId);
|
2431
2451
|
}
|
2432
2452
|
}
|
2433
2453
|
},
|
2434
|
-
}).unsubscribe, [control]);
|
2435
|
-
const updateValues =
|
2454
|
+
}).unsubscribe, [control, name]);
|
2455
|
+
const updateValues = React.useCallback((updatedFieldArrayValues) => {
|
2436
2456
|
_actioned.current = true;
|
2437
2457
|
control._setFieldArray(name, updatedFieldArrayValues);
|
2438
2458
|
}, [control, name]);
|
@@ -2521,7 +2541,7 @@ function useFieldArray(props) {
|
|
2521
2541
|
setFields([...updatedFieldArrayValues]);
|
2522
2542
|
control._setFieldArray(name, [...updatedFieldArrayValues], (data) => data, {}, true, false);
|
2523
2543
|
};
|
2524
|
-
|
2544
|
+
React.useEffect(() => {
|
2525
2545
|
control._state.action = false;
|
2526
2546
|
isWatched(name, control._names) &&
|
2527
2547
|
control._subjects.state.next({
|
@@ -2581,7 +2601,7 @@ function useFieldArray(props) {
|
|
2581
2601
|
control._setValid();
|
2582
2602
|
_actioned.current = false;
|
2583
2603
|
}, [fields, name, control]);
|
2584
|
-
|
2604
|
+
React.useEffect(() => {
|
2585
2605
|
!get(control._formValues, name) && control._setFieldArray(name);
|
2586
2606
|
return () => {
|
2587
2607
|
const updateMounted = (name, value) => {
|
@@ -2596,15 +2616,15 @@ function useFieldArray(props) {
|
|
2596
2616
|
};
|
2597
2617
|
}, [name, control, keyName, shouldUnregister]);
|
2598
2618
|
return {
|
2599
|
-
swap:
|
2600
|
-
move:
|
2601
|
-
prepend:
|
2602
|
-
append:
|
2603
|
-
remove:
|
2604
|
-
insert:
|
2605
|
-
update:
|
2606
|
-
replace:
|
2607
|
-
fields:
|
2619
|
+
swap: React.useCallback(swap, [updateValues, name, control]),
|
2620
|
+
move: React.useCallback(move, [updateValues, name, control]),
|
2621
|
+
prepend: React.useCallback(prepend, [updateValues, name, control]),
|
2622
|
+
append: React.useCallback(append, [updateValues, name, control]),
|
2623
|
+
remove: React.useCallback(remove, [updateValues, name, control]),
|
2624
|
+
insert: React.useCallback(insert$1, [updateValues, name, control]),
|
2625
|
+
update: React.useCallback(update, [updateValues, name, control]),
|
2626
|
+
replace: React.useCallback(replace, [updateValues, name, control]),
|
2627
|
+
fields: React.useMemo(() => fields.map((field, index) => ({
|
2608
2628
|
...field,
|
2609
2629
|
[keyName]: ids.current[index] || generateId(),
|
2610
2630
|
})), [fields, keyName]),
|
@@ -2641,9 +2661,9 @@ function useFieldArray(props) {
|
|
2641
2661
|
* ```
|
2642
2662
|
*/
|
2643
2663
|
function useForm(props = {}) {
|
2644
|
-
const _formControl =
|
2645
|
-
const _values =
|
2646
|
-
const [formState, updateFormState] =
|
2664
|
+
const _formControl = React.useRef(undefined);
|
2665
|
+
const _values = React.useRef(undefined);
|
2666
|
+
const [formState, updateFormState] = React.useState({
|
2647
2667
|
isDirty: false,
|
2648
2668
|
isValidating: false,
|
2649
2669
|
isLoading: isFunction(props.defaultValues),
|
@@ -2695,8 +2715,8 @@ function useForm(props = {}) {
|
|
2695
2715
|
control._formState.isReady = true;
|
2696
2716
|
return sub;
|
2697
2717
|
}, [control]);
|
2698
|
-
|
2699
|
-
|
2718
|
+
React.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
2719
|
+
React.useEffect(() => {
|
2700
2720
|
if (props.mode) {
|
2701
2721
|
control._options.mode = props.mode;
|
2702
2722
|
}
|
@@ -2704,19 +2724,19 @@ function useForm(props = {}) {
|
|
2704
2724
|
control._options.reValidateMode = props.reValidateMode;
|
2705
2725
|
}
|
2706
2726
|
}, [control, props.mode, props.reValidateMode]);
|
2707
|
-
|
2727
|
+
React.useEffect(() => {
|
2708
2728
|
if (props.errors) {
|
2709
2729
|
control._setErrors(props.errors);
|
2710
2730
|
control._focusError();
|
2711
2731
|
}
|
2712
2732
|
}, [control, props.errors]);
|
2713
|
-
|
2733
|
+
React.useEffect(() => {
|
2714
2734
|
props.shouldUnregister &&
|
2715
2735
|
control._subjects.state.next({
|
2716
2736
|
values: control._getWatch(),
|
2717
2737
|
});
|
2718
2738
|
}, [control, props.shouldUnregister]);
|
2719
|
-
|
2739
|
+
React.useEffect(() => {
|
2720
2740
|
if (control._proxyFormState.isDirty) {
|
2721
2741
|
const isDirty = control._getDirty();
|
2722
2742
|
if (isDirty !== formState.isDirty) {
|
@@ -2726,7 +2746,7 @@ function useForm(props = {}) {
|
|
2726
2746
|
}
|
2727
2747
|
}
|
2728
2748
|
}, [control, formState.isDirty]);
|
2729
|
-
|
2749
|
+
React.useEffect(() => {
|
2730
2750
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
2731
2751
|
control._reset(props.values, {
|
2732
2752
|
keepFieldsRef: true,
|
@@ -2739,7 +2759,7 @@ function useForm(props = {}) {
|
|
2739
2759
|
control._resetDefaultValues();
|
2740
2760
|
}
|
2741
2761
|
}, [control, props.values]);
|
2742
|
-
|
2762
|
+
React.useEffect(() => {
|
2743
2763
|
if (!control._state.mount) {
|
2744
2764
|
control._setValid();
|
2745
2765
|
control._state.mount = true;
|