react-hook-form 7.65.0 → 7.66.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 +61 -25
- 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 +2 -1
- package/dist/react-server.esm.mjs.map +1 -1
- package/dist/useFormContext.d.ts +1 -1
- package/dist/watch.d.ts +1 -1
- package/dist/watch.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.mjs
CHANGED
|
@@ -161,7 +161,7 @@ HookFormContext.displayName = 'HookFormContext';
|
|
|
161
161
|
*/
|
|
162
162
|
const useFormContext = () => React.useContext(HookFormContext);
|
|
163
163
|
/**
|
|
164
|
-
* A provider component that propagates the `useForm` methods to all children components via [React Context](https://
|
|
164
|
+
* A provider component that propagates the `useForm` methods to all children components via [React Context](https://react.dev/reference/react/useContext) API. To be used with {@link useFormContext}.
|
|
165
165
|
*
|
|
166
166
|
* @remarks
|
|
167
167
|
* [API](https://react-hook-form.com/docs/useformcontext) • [Demo](https://codesandbox.io/s/react-hook-form-v7-form-context-ytudi)
|
|
@@ -353,33 +353,68 @@ function useWatch(props) {
|
|
|
353
353
|
const _defaultValue = React.useRef(defaultValue);
|
|
354
354
|
const _compute = React.useRef(compute);
|
|
355
355
|
const _computeFormValues = React.useRef(undefined);
|
|
356
|
+
const _prevControl = React.useRef(control);
|
|
357
|
+
const _prevName = React.useRef(name);
|
|
356
358
|
_compute.current = compute;
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
updateValue(formValues);
|
|
359
|
+
const [value, updateValue] = React.useState(() => {
|
|
360
|
+
const defaultValue = control._getWatch(name, _defaultValue.current);
|
|
361
|
+
return _compute.current ? _compute.current(defaultValue) : defaultValue;
|
|
362
|
+
});
|
|
363
|
+
const getCurrentOutput = React.useCallback((values) => {
|
|
364
|
+
const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
|
|
365
|
+
return _compute.current ? _compute.current(formValues) : formValues;
|
|
366
|
+
}, [control._formValues, control._names, name]);
|
|
367
|
+
const refreshValue = React.useCallback((values) => {
|
|
368
|
+
if (!disabled) {
|
|
369
|
+
const formValues = generateWatchOutput(name, control._names, values || control._formValues, false, _defaultValue.current);
|
|
370
|
+
if (_compute.current) {
|
|
371
|
+
const computedFormValues = _compute.current(formValues);
|
|
372
|
+
if (!deepEqual(computedFormValues, _computeFormValues.current)) {
|
|
373
|
+
updateValue(computedFormValues);
|
|
374
|
+
_computeFormValues.current = computedFormValues;
|
|
377
375
|
}
|
|
378
376
|
}
|
|
379
|
-
|
|
380
|
-
|
|
377
|
+
else {
|
|
378
|
+
updateValue(formValues);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}, [control._formValues, control._names, disabled, name]);
|
|
382
|
+
useIsomorphicLayoutEffect(() => {
|
|
383
|
+
if (_prevControl.current !== control ||
|
|
384
|
+
!deepEqual(_prevName.current, name)) {
|
|
385
|
+
_prevControl.current = control;
|
|
386
|
+
_prevName.current = name;
|
|
387
|
+
refreshValue();
|
|
388
|
+
}
|
|
389
|
+
return control._subscribe({
|
|
390
|
+
name,
|
|
391
|
+
formState: {
|
|
392
|
+
values: true,
|
|
393
|
+
},
|
|
394
|
+
exact,
|
|
395
|
+
callback: (formState) => {
|
|
396
|
+
refreshValue(formState.values);
|
|
397
|
+
},
|
|
398
|
+
});
|
|
399
|
+
}, [control, exact, name, refreshValue]);
|
|
381
400
|
React.useEffect(() => control._removeUnmounted());
|
|
382
|
-
|
|
401
|
+
// If name or control changed for this render, synchronously reflect the
|
|
402
|
+
// latest value so callers (like useController) see the correct value
|
|
403
|
+
// immediately on the same render.
|
|
404
|
+
// Optimize: Check control reference first before expensive deepEqual
|
|
405
|
+
const controlChanged = _prevControl.current !== control;
|
|
406
|
+
const prevName = _prevName.current;
|
|
407
|
+
// Cache the computed output to avoid duplicate calls within the same render
|
|
408
|
+
// We include shouldReturnImmediate in deps to ensure proper recomputation
|
|
409
|
+
const computedOutput = React.useMemo(() => {
|
|
410
|
+
if (disabled) {
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
const nameChanged = !controlChanged && !deepEqual(prevName, name);
|
|
414
|
+
const shouldReturnImmediate = controlChanged || nameChanged;
|
|
415
|
+
return shouldReturnImmediate ? getCurrentOutput() : null;
|
|
416
|
+
}, [disabled, controlChanged, name, prevName, getCurrentOutput]);
|
|
417
|
+
return computedOutput !== null ? computedOutput : value;
|
|
383
418
|
}
|
|
384
419
|
|
|
385
420
|
/**
|
|
@@ -2203,7 +2238,8 @@ function createFormControl(props = {}) {
|
|
|
2203
2238
|
_state.mount =
|
|
2204
2239
|
!_proxyFormState.isValid ||
|
|
2205
2240
|
!!keepStateOptions.keepIsValid ||
|
|
2206
|
-
!!keepStateOptions.keepDirtyValues
|
|
2241
|
+
!!keepStateOptions.keepDirtyValues ||
|
|
2242
|
+
(!_options.shouldUnregister && !isEmptyObject(values));
|
|
2207
2243
|
_state.watch = !!_options.shouldUnregister;
|
|
2208
2244
|
_subjects.state.next({
|
|
2209
2245
|
submitCount: keepStateOptions.keepSubmitCount
|