react-hook-form 7.55.0-next.9 → 7.56.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/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.mjs +84 -64
- 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 +1 -0
- 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/useDeepEqualEffect.d.ts +3 -0
- package/dist/useDeepEqualEffect.d.ts.map +1 -0
- package/dist/useForm.d.ts.map +1 -1
- package/dist/useFormState.d.ts +1 -2
- package/dist/useFormState.d.ts.map +1 -1
- package/dist/useWatch.d.ts.map +1 -1
- package/package.json +17 -17
package/dist/index.esm.mjs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { useRef, useEffect } from 'react';
|
2
2
|
|
3
3
|
var isCheckBoxInput = (element) => element.type === 'checkbox';
|
4
4
|
|
@@ -216,6 +216,48 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
216
216
|
return result;
|
217
217
|
};
|
218
218
|
|
219
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
220
|
+
|
221
|
+
function deepEqual(object1, object2) {
|
222
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
223
|
+
return object1 === object2;
|
224
|
+
}
|
225
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
226
|
+
return object1.getTime() === object2.getTime();
|
227
|
+
}
|
228
|
+
const keys1 = Object.keys(object1);
|
229
|
+
const keys2 = Object.keys(object2);
|
230
|
+
if (keys1.length !== keys2.length) {
|
231
|
+
return false;
|
232
|
+
}
|
233
|
+
for (const key of keys1) {
|
234
|
+
const val1 = object1[key];
|
235
|
+
if (!keys2.includes(key)) {
|
236
|
+
return false;
|
237
|
+
}
|
238
|
+
if (key !== 'ref') {
|
239
|
+
const val2 = object2[key];
|
240
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
241
|
+
(isObject(val1) && isObject(val2)) ||
|
242
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
243
|
+
? !deepEqual(val1, val2)
|
244
|
+
: val1 !== val2) {
|
245
|
+
return false;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
}
|
249
|
+
return true;
|
250
|
+
}
|
251
|
+
|
252
|
+
const useDeepEqualEffect = (effect, deps) => {
|
253
|
+
const ref = useRef(deps);
|
254
|
+
if (!deepEqual(deps, ref.current)) {
|
255
|
+
ref.current = deps;
|
256
|
+
}
|
257
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
258
|
+
useEffect(effect, ref.current);
|
259
|
+
};
|
260
|
+
|
219
261
|
/**
|
220
262
|
* This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
|
221
263
|
*
|
@@ -260,10 +302,8 @@ function useFormState(props) {
|
|
260
302
|
isValid: false,
|
261
303
|
errors: false,
|
262
304
|
});
|
263
|
-
|
264
|
-
|
265
|
-
React.useEffect(() => control._subscribe({
|
266
|
-
name: _name.current,
|
305
|
+
useDeepEqualEffect(() => control._subscribe({
|
306
|
+
name: name,
|
267
307
|
formState: _localProxyFormState.current,
|
268
308
|
exact,
|
269
309
|
callback: (formState) => {
|
@@ -273,7 +313,7 @@ function useFormState(props) {
|
|
273
313
|
...formState,
|
274
314
|
});
|
275
315
|
},
|
276
|
-
}), [
|
316
|
+
}), [name, disabled, exact]);
|
277
317
|
React.useEffect(() => {
|
278
318
|
_localProxyFormState.current.isValid && control._setValid(true);
|
279
319
|
}, [control]);
|
@@ -313,19 +353,16 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
313
353
|
function useWatch(props) {
|
314
354
|
const methods = useFormContext();
|
315
355
|
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
316
|
-
const
|
317
|
-
|
318
|
-
|
319
|
-
React.useEffect(() => control._subscribe({
|
320
|
-
name: _name.current,
|
356
|
+
const [value, updateValue] = React.useState(control._getWatch(name, defaultValue));
|
357
|
+
useDeepEqualEffect(() => control._subscribe({
|
358
|
+
name: name,
|
321
359
|
formState: {
|
322
360
|
values: true,
|
323
361
|
},
|
324
362
|
exact,
|
325
363
|
callback: (formState) => !disabled &&
|
326
|
-
updateValue(generateWatchOutput(
|
327
|
-
}), [
|
328
|
-
const [value, updateValue] = React.useState(control._getWatch(name, defaultValue));
|
364
|
+
updateValue(generateWatchOutput(name, control._names, formState.values || control._formValues, false, defaultValue)),
|
365
|
+
}), [name, defaultValue, disabled, exact]);
|
329
366
|
React.useEffect(() => control._removeUnmounted());
|
330
367
|
return value;
|
331
368
|
}
|
@@ -675,39 +712,6 @@ var createSubject = () => {
|
|
675
712
|
};
|
676
713
|
};
|
677
714
|
|
678
|
-
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
679
|
-
|
680
|
-
function deepEqual(object1, object2) {
|
681
|
-
if (isPrimitive(object1) || isPrimitive(object2)) {
|
682
|
-
return object1 === object2;
|
683
|
-
}
|
684
|
-
if (isDateObject(object1) && isDateObject(object2)) {
|
685
|
-
return object1.getTime() === object2.getTime();
|
686
|
-
}
|
687
|
-
const keys1 = Object.keys(object1);
|
688
|
-
const keys2 = Object.keys(object2);
|
689
|
-
if (keys1.length !== keys2.length) {
|
690
|
-
return false;
|
691
|
-
}
|
692
|
-
for (const key of keys1) {
|
693
|
-
const val1 = object1[key];
|
694
|
-
if (!keys2.includes(key)) {
|
695
|
-
return false;
|
696
|
-
}
|
697
|
-
if (key !== 'ref') {
|
698
|
-
const val2 = object2[key];
|
699
|
-
if ((isDateObject(val1) && isDateObject(val2)) ||
|
700
|
-
(isObject(val1) && isObject(val2)) ||
|
701
|
-
(Array.isArray(val1) && Array.isArray(val2))
|
702
|
-
? !deepEqual(val1, val2)
|
703
|
-
: val1 !== val2) {
|
704
|
-
return false;
|
705
|
-
}
|
706
|
-
}
|
707
|
-
}
|
708
|
-
return true;
|
709
|
-
}
|
710
|
-
|
711
715
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
712
716
|
|
713
717
|
var isFileInput = (element) => element.type === 'file';
|
@@ -1256,6 +1260,7 @@ function createFormControl(props = {}) {
|
|
1256
1260
|
let _formState = {
|
1257
1261
|
submitCount: 0,
|
1258
1262
|
isDirty: false,
|
1263
|
+
isReady: false,
|
1259
1264
|
isLoading: isFunction(_options.defaultValues),
|
1260
1265
|
isValidating: false,
|
1261
1266
|
isSubmitted: false,
|
@@ -2581,6 +2586,7 @@ function useFieldArray(props) {
|
|
2581
2586
|
};
|
2582
2587
|
}
|
2583
2588
|
|
2589
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
2584
2590
|
/**
|
2585
2591
|
* Custom hook to manage the entire form.
|
2586
2592
|
*
|
@@ -2627,6 +2633,7 @@ function useForm(props = {}) {
|
|
2627
2633
|
validatingFields: {},
|
2628
2634
|
errors: props.errors || {},
|
2629
2635
|
disabled: props.disabled || false,
|
2636
|
+
isReady: false,
|
2630
2637
|
defaultValues: isFunction(props.defaultValues)
|
2631
2638
|
? undefined
|
2632
2639
|
: props.defaultValues,
|
@@ -2644,12 +2651,36 @@ function useForm(props = {}) {
|
|
2644
2651
|
}
|
2645
2652
|
const control = _formControl.current.control;
|
2646
2653
|
control._options = props;
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2650
|
-
|
2651
|
-
|
2654
|
+
useIsomorphicLayoutEffect(() => {
|
2655
|
+
const sub = control._subscribe({
|
2656
|
+
formState: control._proxyFormState,
|
2657
|
+
callback: () => updateFormState({ ...control._formState }),
|
2658
|
+
reRenderRoot: true,
|
2659
|
+
});
|
2660
|
+
updateFormState((data) => ({
|
2661
|
+
...data,
|
2662
|
+
isReady: true,
|
2663
|
+
}));
|
2664
|
+
return sub;
|
2665
|
+
}, [control]);
|
2652
2666
|
React.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
2667
|
+
React.useEffect(() => {
|
2668
|
+
if (props.mode) {
|
2669
|
+
control._options.mode = props.mode;
|
2670
|
+
}
|
2671
|
+
if (props.reValidateMode) {
|
2672
|
+
control._options.reValidateMode = props.reValidateMode;
|
2673
|
+
}
|
2674
|
+
if (props.errors && !isEmptyObject(props.errors)) {
|
2675
|
+
control._setErrors(props.errors);
|
2676
|
+
}
|
2677
|
+
}, [control, props.errors, props.mode, props.reValidateMode]);
|
2678
|
+
React.useEffect(() => {
|
2679
|
+
props.shouldUnregister &&
|
2680
|
+
control._subjects.state.next({
|
2681
|
+
values: control._getWatch(),
|
2682
|
+
});
|
2683
|
+
}, [control, props.shouldUnregister]);
|
2653
2684
|
React.useEffect(() => {
|
2654
2685
|
if (control._proxyFormState.isDirty) {
|
2655
2686
|
const isDirty = control._getDirty();
|
@@ -2669,12 +2700,7 @@ function useForm(props = {}) {
|
|
2669
2700
|
else {
|
2670
2701
|
control._resetDefaultValues();
|
2671
2702
|
}
|
2672
|
-
}, [props.values
|
2673
|
-
React.useEffect(() => {
|
2674
|
-
if (props.errors && !isEmptyObject(props.errors)) {
|
2675
|
-
control._setErrors(props.errors);
|
2676
|
-
}
|
2677
|
-
}, [props.errors, control]);
|
2703
|
+
}, [control, props.values]);
|
2678
2704
|
React.useEffect(() => {
|
2679
2705
|
if (!control._state.mount) {
|
2680
2706
|
control._setValid();
|
@@ -2686,12 +2712,6 @@ function useForm(props = {}) {
|
|
2686
2712
|
}
|
2687
2713
|
control._removeUnmounted();
|
2688
2714
|
});
|
2689
|
-
React.useEffect(() => {
|
2690
|
-
props.shouldUnregister &&
|
2691
|
-
control._subjects.state.next({
|
2692
|
-
values: control._getWatch(),
|
2693
|
-
});
|
2694
|
-
}, [props.shouldUnregister, control]);
|
2695
2715
|
_formControl.current.formState = getProxyFormState(formState, control);
|
2696
2716
|
return _formControl.current;
|
2697
2717
|
}
|