react-hook-form 7.56.0 → 7.57.0-next.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 +30 -28
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +86 -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/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/useDeepEqualEffect.d.ts +2 -2
- package/dist/useDeepEqualEffect.d.ts.map +1 -1
- package/dist/useFieldArray.d.ts.map +1 -1
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useWatch.d.ts +91 -0
- package/dist/useWatch.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.esm.mjs
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
import
|
1
|
+
import * as React from 'react';
|
2
|
+
import React__default, { useEffect } from 'react';
|
2
3
|
|
3
4
|
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
4
5
|
|
@@ -130,7 +131,7 @@ const INPUT_VALIDATION_RULES = {
|
|
130
131
|
validate: 'validate',
|
131
132
|
};
|
132
133
|
|
133
|
-
const HookFormContext =
|
134
|
+
const HookFormContext = React__default.createContext(null);
|
134
135
|
/**
|
135
136
|
* 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}.
|
136
137
|
*
|
@@ -161,7 +162,7 @@ const HookFormContext = React.createContext(null);
|
|
161
162
|
* }
|
162
163
|
* ```
|
163
164
|
*/
|
164
|
-
const useFormContext = () =>
|
165
|
+
const useFormContext = () => React__default.useContext(HookFormContext);
|
165
166
|
/**
|
166
167
|
* 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}.
|
167
168
|
*
|
@@ -194,7 +195,7 @@ const useFormContext = () => React.useContext(HookFormContext);
|
|
194
195
|
*/
|
195
196
|
const FormProvider = (props) => {
|
196
197
|
const { children, ...data } = props;
|
197
|
-
return (
|
198
|
+
return (React__default.createElement(HookFormContext.Provider, { value: data }, children));
|
198
199
|
};
|
199
200
|
|
200
201
|
var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => {
|
@@ -250,12 +251,12 @@ function deepEqual(object1, object2) {
|
|
250
251
|
}
|
251
252
|
|
252
253
|
const useDeepEqualEffect = (effect, deps) => {
|
253
|
-
const ref = useRef(deps);
|
254
|
+
const ref = React.useRef(deps);
|
254
255
|
if (!deepEqual(deps, ref.current)) {
|
255
256
|
ref.current = deps;
|
256
257
|
}
|
257
258
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
258
|
-
useEffect(effect, ref.current);
|
259
|
+
React.useEffect(effect, ref.current);
|
259
260
|
};
|
260
261
|
|
261
262
|
/**
|
@@ -291,8 +292,8 @@ const useDeepEqualEffect = (effect, deps) => {
|
|
291
292
|
function useFormState(props) {
|
292
293
|
const methods = useFormContext();
|
293
294
|
const { control = methods.control, disabled, name, exact } = props || {};
|
294
|
-
const [formState, updateFormState] =
|
295
|
-
const _localProxyFormState =
|
295
|
+
const [formState, updateFormState] = React__default.useState(control._formState);
|
296
|
+
const _localProxyFormState = React__default.useRef({
|
296
297
|
isDirty: false,
|
297
298
|
isLoading: false,
|
298
299
|
dirtyFields: false,
|
@@ -314,10 +315,10 @@ function useFormState(props) {
|
|
314
315
|
});
|
315
316
|
},
|
316
317
|
}), [name, disabled, exact]);
|
317
|
-
|
318
|
+
React__default.useEffect(() => {
|
318
319
|
_localProxyFormState.current.isValid && control._setValid(true);
|
319
320
|
}, [control]);
|
320
|
-
return
|
321
|
+
return React__default.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]);
|
321
322
|
}
|
322
323
|
|
323
324
|
var isString = (value) => typeof value === 'string';
|
@@ -352,18 +353,35 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
352
353
|
*/
|
353
354
|
function useWatch(props) {
|
354
355
|
const methods = useFormContext();
|
355
|
-
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
356
|
-
const
|
356
|
+
const { control = methods.control, name, defaultValue, disabled, exact, compute, } = props || {};
|
357
|
+
const _compute = React__default.useRef(compute);
|
358
|
+
const _computeFormValues = React__default.useRef(undefined);
|
359
|
+
_compute.current = compute;
|
360
|
+
const defaultValueMemo = React__default.useMemo(() => control._getWatch(name, defaultValue), [control, name, defaultValue]);
|
361
|
+
const [value, updateValue] = React__default.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo);
|
357
362
|
useDeepEqualEffect(() => control._subscribe({
|
358
363
|
name: name,
|
359
364
|
formState: {
|
360
365
|
values: true,
|
361
366
|
},
|
362
367
|
exact,
|
363
|
-
callback: (formState) =>
|
364
|
-
|
365
|
-
|
366
|
-
|
368
|
+
callback: (formState) => {
|
369
|
+
if (!disabled) {
|
370
|
+
const formValues = generateWatchOutput(name, control._names, formState.values || control._formValues, false, defaultValue);
|
371
|
+
if (_compute.current) {
|
372
|
+
const computedFormValues = _compute.current(formValues);
|
373
|
+
if (!deepEqual(computedFormValues, _computeFormValues.current)) {
|
374
|
+
updateValue(computedFormValues);
|
375
|
+
_computeFormValues.current = computedFormValues;
|
376
|
+
}
|
377
|
+
}
|
378
|
+
else {
|
379
|
+
updateValue(formValues);
|
380
|
+
}
|
381
|
+
}
|
382
|
+
},
|
383
|
+
}), [defaultValue, disabled, name, exact]);
|
384
|
+
React__default.useEffect(() => control._removeUnmounted());
|
367
385
|
return value;
|
368
386
|
}
|
369
387
|
|
@@ -393,12 +411,13 @@ function useWatch(props) {
|
|
393
411
|
*/
|
394
412
|
function useController(props) {
|
395
413
|
const methods = useFormContext();
|
396
|
-
const { name, disabled, control = methods.control, shouldUnregister } = props;
|
414
|
+
const { name, disabled, control = methods.control, shouldUnregister, defaultValue, } = props;
|
397
415
|
const isArrayField = isNameInFieldArray(control._names.array, name);
|
416
|
+
const defaultValueMemo = React__default.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]);
|
398
417
|
const value = useWatch({
|
399
418
|
control,
|
400
419
|
name,
|
401
|
-
defaultValue:
|
420
|
+
defaultValue: defaultValueMemo,
|
402
421
|
exact: true,
|
403
422
|
});
|
404
423
|
const formState = useFormState({
|
@@ -406,13 +425,14 @@ function useController(props) {
|
|
406
425
|
name,
|
407
426
|
exact: true,
|
408
427
|
});
|
409
|
-
const _props =
|
410
|
-
const _registerProps =
|
428
|
+
const _props = React__default.useRef(props);
|
429
|
+
const _registerProps = React__default.useRef(control.register(name, {
|
411
430
|
...props.rules,
|
412
431
|
value,
|
413
432
|
...(isBoolean(props.disabled) ? { disabled: props.disabled } : {}),
|
414
433
|
}));
|
415
|
-
|
434
|
+
_props.current = props;
|
435
|
+
const fieldState = React__default.useMemo(() => Object.defineProperties({}, {
|
416
436
|
invalid: {
|
417
437
|
enumerable: true,
|
418
438
|
get: () => !!get(formState.errors, name),
|
@@ -434,32 +454,27 @@ function useController(props) {
|
|
434
454
|
get: () => get(formState.errors, name),
|
435
455
|
},
|
436
456
|
}), [formState, name]);
|
437
|
-
const onChange =
|
457
|
+
const onChange = React__default.useCallback((event) => _registerProps.current.onChange({
|
438
458
|
target: {
|
439
459
|
value: getEventValue(event),
|
440
460
|
name: name,
|
441
461
|
},
|
442
462
|
type: EVENTS.CHANGE,
|
443
463
|
}), [name]);
|
444
|
-
const onBlur =
|
464
|
+
const onBlur = React__default.useCallback(() => _registerProps.current.onBlur({
|
445
465
|
target: {
|
446
466
|
value: get(control._formValues, name),
|
447
467
|
name: name,
|
448
468
|
},
|
449
469
|
type: EVENTS.BLUR,
|
450
470
|
}), [name, control._formValues]);
|
451
|
-
const ref =
|
471
|
+
const ref = React__default.useCallback((elm) => {
|
452
472
|
const field = get(control._fields, name);
|
453
473
|
if (field && elm) {
|
454
|
-
field._f.ref =
|
455
|
-
focus: () => elm.focus(),
|
456
|
-
select: () => elm.select(),
|
457
|
-
setCustomValidity: (message) => elm.setCustomValidity(message),
|
458
|
-
reportValidity: () => elm.reportValidity(),
|
459
|
-
};
|
474
|
+
field._f.ref = elm;
|
460
475
|
}
|
461
476
|
}, [control._fields, name]);
|
462
|
-
const field =
|
477
|
+
const field = React__default.useMemo(() => ({
|
463
478
|
name,
|
464
479
|
value,
|
465
480
|
...(isBoolean(disabled) || formState.disabled
|
@@ -469,7 +484,7 @@ function useController(props) {
|
|
469
484
|
onBlur,
|
470
485
|
ref,
|
471
486
|
}), [name, disabled, formState.disabled, onChange, onBlur, ref, value]);
|
472
|
-
|
487
|
+
React__default.useEffect(() => {
|
473
488
|
const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
|
474
489
|
control.register(name, {
|
475
490
|
..._props.current.rules,
|
@@ -500,13 +515,13 @@ function useController(props) {
|
|
500
515
|
: updateMounted(name, false);
|
501
516
|
};
|
502
517
|
}, [name, control, isArrayField, shouldUnregister]);
|
503
|
-
|
518
|
+
React__default.useEffect(() => {
|
504
519
|
control._setDisabledField({
|
505
520
|
disabled,
|
506
521
|
name,
|
507
522
|
});
|
508
523
|
}, [disabled, name, control]);
|
509
|
-
return
|
524
|
+
return React__default.useMemo(() => ({
|
510
525
|
field,
|
511
526
|
formState,
|
512
527
|
fieldState,
|
@@ -598,7 +613,7 @@ const POST_REQUEST = 'post';
|
|
598
613
|
*/
|
599
614
|
function Form(props) {
|
600
615
|
const methods = useFormContext();
|
601
|
-
const [mounted, setMounted] =
|
616
|
+
const [mounted, setMounted] = React__default.useState(false);
|
602
617
|
const { control = methods.control, onSubmit, children, action, method = POST_REQUEST, headers, encType, onError, render, onSuccess, validateStatus, ...rest } = props;
|
603
618
|
const submit = async (event) => {
|
604
619
|
let hasError = false;
|
@@ -664,12 +679,12 @@ function Form(props) {
|
|
664
679
|
});
|
665
680
|
}
|
666
681
|
};
|
667
|
-
|
682
|
+
React__default.useEffect(() => {
|
668
683
|
setMounted(true);
|
669
684
|
}, []);
|
670
|
-
return render ? (
|
685
|
+
return render ? (React__default.createElement(React__default.Fragment, null, render({
|
671
686
|
submit,
|
672
|
-
}))) : (
|
687
|
+
}))) : (React__default.createElement("form", { noValidate: mounted, action: action, method: method, encType: encType, onSubmit: submit, ...rest }, children));
|
673
688
|
}
|
674
689
|
|
675
690
|
var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria
|
@@ -2386,28 +2401,26 @@ var updateAt = (fieldValues, index, value) => {
|
|
2386
2401
|
function useFieldArray(props) {
|
2387
2402
|
const methods = useFormContext();
|
2388
2403
|
const { control = methods.control, name, keyName = 'id', shouldUnregister, rules, } = props;
|
2389
|
-
const [fields, setFields] =
|
2390
|
-
const ids =
|
2391
|
-
const _fieldIds =
|
2392
|
-
const
|
2393
|
-
const _actioned = React.useRef(false);
|
2394
|
-
_name.current = name;
|
2404
|
+
const [fields, setFields] = React__default.useState(control._getFieldArray(name));
|
2405
|
+
const ids = React__default.useRef(control._getFieldArray(name).map(generateId));
|
2406
|
+
const _fieldIds = React__default.useRef(fields);
|
2407
|
+
const _actioned = React__default.useRef(false);
|
2395
2408
|
_fieldIds.current = fields;
|
2396
2409
|
control._names.array.add(name);
|
2397
|
-
rules &&
|
2398
|
-
control.register(name, rules);
|
2399
|
-
|
2410
|
+
React__default.useMemo(() => rules &&
|
2411
|
+
control.register(name, rules), [control, rules, name]);
|
2412
|
+
useEffect(() => control._subjects.array.subscribe({
|
2400
2413
|
next: ({ values, name: fieldArrayName, }) => {
|
2401
|
-
if (fieldArrayName ===
|
2402
|
-
const fieldValues = get(values,
|
2414
|
+
if (fieldArrayName === name || !fieldArrayName) {
|
2415
|
+
const fieldValues = get(values, name);
|
2403
2416
|
if (Array.isArray(fieldValues)) {
|
2404
2417
|
setFields(fieldValues);
|
2405
2418
|
ids.current = fieldValues.map(generateId);
|
2406
2419
|
}
|
2407
2420
|
}
|
2408
2421
|
},
|
2409
|
-
}).unsubscribe, [control]);
|
2410
|
-
const updateValues =
|
2422
|
+
}).unsubscribe, [control, name]);
|
2423
|
+
const updateValues = React__default.useCallback((updatedFieldArrayValues) => {
|
2411
2424
|
_actioned.current = true;
|
2412
2425
|
control._setFieldArray(name, updatedFieldArrayValues);
|
2413
2426
|
}, [control, name]);
|
@@ -2496,7 +2509,7 @@ function useFieldArray(props) {
|
|
2496
2509
|
setFields([...updatedFieldArrayValues]);
|
2497
2510
|
control._setFieldArray(name, [...updatedFieldArrayValues], (data) => data, {}, true, false);
|
2498
2511
|
};
|
2499
|
-
|
2512
|
+
React__default.useEffect(() => {
|
2500
2513
|
control._state.action = false;
|
2501
2514
|
isWatched(name, control._names) &&
|
2502
2515
|
control._subjects.state.next({
|
@@ -2556,7 +2569,7 @@ function useFieldArray(props) {
|
|
2556
2569
|
control._setValid();
|
2557
2570
|
_actioned.current = false;
|
2558
2571
|
}, [fields, name, control]);
|
2559
|
-
|
2572
|
+
React__default.useEffect(() => {
|
2560
2573
|
!get(control._formValues, name) && control._setFieldArray(name);
|
2561
2574
|
return () => {
|
2562
2575
|
const updateMounted = (name, value) => {
|
@@ -2571,22 +2584,22 @@ function useFieldArray(props) {
|
|
2571
2584
|
};
|
2572
2585
|
}, [name, control, keyName, shouldUnregister]);
|
2573
2586
|
return {
|
2574
|
-
swap:
|
2575
|
-
move:
|
2576
|
-
prepend:
|
2577
|
-
append:
|
2578
|
-
remove:
|
2579
|
-
insert:
|
2580
|
-
update:
|
2581
|
-
replace:
|
2582
|
-
fields:
|
2587
|
+
swap: React__default.useCallback(swap, [updateValues, name, control]),
|
2588
|
+
move: React__default.useCallback(move, [updateValues, name, control]),
|
2589
|
+
prepend: React__default.useCallback(prepend, [updateValues, name, control]),
|
2590
|
+
append: React__default.useCallback(append, [updateValues, name, control]),
|
2591
|
+
remove: React__default.useCallback(remove, [updateValues, name, control]),
|
2592
|
+
insert: React__default.useCallback(insert$1, [updateValues, name, control]),
|
2593
|
+
update: React__default.useCallback(update, [updateValues, name, control]),
|
2594
|
+
replace: React__default.useCallback(replace, [updateValues, name, control]),
|
2595
|
+
fields: React__default.useMemo(() => fields.map((field, index) => ({
|
2583
2596
|
...field,
|
2584
2597
|
[keyName]: ids.current[index] || generateId(),
|
2585
2598
|
})), [fields, keyName]),
|
2586
2599
|
};
|
2587
2600
|
}
|
2588
2601
|
|
2589
|
-
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ?
|
2602
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React__default.useLayoutEffect : React__default.useEffect;
|
2590
2603
|
/**
|
2591
2604
|
* Custom hook to manage the entire form.
|
2592
2605
|
*
|
@@ -2617,9 +2630,9 @@ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayou
|
|
2617
2630
|
* ```
|
2618
2631
|
*/
|
2619
2632
|
function useForm(props = {}) {
|
2620
|
-
const _formControl =
|
2621
|
-
const _values =
|
2622
|
-
const [formState, updateFormState] =
|
2633
|
+
const _formControl = React__default.useRef(undefined);
|
2634
|
+
const _values = React__default.useRef(undefined);
|
2635
|
+
const [formState, updateFormState] = React__default.useState({
|
2623
2636
|
isDirty: false,
|
2624
2637
|
isValidating: false,
|
2625
2638
|
isLoading: isFunction(props.defaultValues),
|
@@ -2661,10 +2674,11 @@ function useForm(props = {}) {
|
|
2661
2674
|
...data,
|
2662
2675
|
isReady: true,
|
2663
2676
|
}));
|
2677
|
+
control._formState.isReady = true;
|
2664
2678
|
return sub;
|
2665
2679
|
}, [control]);
|
2666
|
-
|
2667
|
-
|
2680
|
+
React__default.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
2681
|
+
React__default.useEffect(() => {
|
2668
2682
|
if (props.mode) {
|
2669
2683
|
control._options.mode = props.mode;
|
2670
2684
|
}
|
@@ -2675,13 +2689,13 @@ function useForm(props = {}) {
|
|
2675
2689
|
control._setErrors(props.errors);
|
2676
2690
|
}
|
2677
2691
|
}, [control, props.errors, props.mode, props.reValidateMode]);
|
2678
|
-
|
2692
|
+
React__default.useEffect(() => {
|
2679
2693
|
props.shouldUnregister &&
|
2680
2694
|
control._subjects.state.next({
|
2681
2695
|
values: control._getWatch(),
|
2682
2696
|
});
|
2683
2697
|
}, [control, props.shouldUnregister]);
|
2684
|
-
|
2698
|
+
React__default.useEffect(() => {
|
2685
2699
|
if (control._proxyFormState.isDirty) {
|
2686
2700
|
const isDirty = control._getDirty();
|
2687
2701
|
if (isDirty !== formState.isDirty) {
|
@@ -2691,7 +2705,7 @@ function useForm(props = {}) {
|
|
2691
2705
|
}
|
2692
2706
|
}
|
2693
2707
|
}, [control, formState.isDirty]);
|
2694
|
-
|
2708
|
+
React__default.useEffect(() => {
|
2695
2709
|
if (props.values && !deepEqual(props.values, _values.current)) {
|
2696
2710
|
control._reset(props.values, control._options.resetOptions);
|
2697
2711
|
_values.current = props.values;
|
@@ -2701,7 +2715,7 @@ function useForm(props = {}) {
|
|
2701
2715
|
control._resetDefaultValues();
|
2702
2716
|
}
|
2703
2717
|
}, [control, props.values]);
|
2704
|
-
|
2718
|
+
React__default.useEffect(() => {
|
2705
2719
|
if (!control._state.mount) {
|
2706
2720
|
control._setValid();
|
2707
2721
|
control._state.mount = true;
|