react-hook-form 7.23.0 → 7.25.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.
@@ -231,9 +231,7 @@ function useController(props) {
231
231
  control,
232
232
  name,
233
233
  });
234
- const _name = React.useRef(name);
235
- _name.current = name;
236
- const registerProps = control.register(name, Object.assign(Object.assign({}, props.rules), { value }));
234
+ const _registerProps = React.useRef(control.register(name, Object.assign(Object.assign({}, props.rules), { value })));
237
235
  React.useEffect(() => {
238
236
  const updateMounted = (name, value) => {
239
237
  const field = get(control._fields, name);
@@ -244,36 +242,36 @@ function useController(props) {
244
242
  updateMounted(name, true);
245
243
  return () => {
246
244
  const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister;
247
- isArrayField
245
+ (isArrayField
248
246
  ? _shouldUnregisterField && !control._stateFlags.action
249
- : _shouldUnregisterField
250
- ? control.unregister(name)
251
- : updateMounted(name, false);
247
+ : _shouldUnregisterField)
248
+ ? control.unregister(name)
249
+ : updateMounted(name, false);
252
250
  };
253
251
  }, [name, control, isArrayField, shouldUnregister]);
254
252
  return {
255
253
  field: {
256
- onChange: (event) => {
257
- registerProps.onChange({
254
+ name,
255
+ value,
256
+ onChange: React.useCallback((event) => {
257
+ _registerProps.current.onChange({
258
258
  target: {
259
259
  value: getEventValue(event),
260
260
  name: name,
261
261
  },
262
262
  type: EVENTS.CHANGE,
263
263
  });
264
- },
265
- onBlur: () => {
266
- registerProps.onBlur({
264
+ }, [name]),
265
+ onBlur: React.useCallback(() => {
266
+ _registerProps.current.onBlur({
267
267
  target: {
268
268
  value: get(control._formValues, name),
269
269
  name: name,
270
270
  },
271
271
  type: EVENTS.BLUR,
272
272
  });
273
- },
274
- name,
275
- value,
276
- ref: (elm) => {
273
+ }, [name, control]),
274
+ ref: React.useCallback((elm) => {
277
275
  const field = get(control._fields, name);
278
276
  if (elm && field && elm.focus) {
279
277
  field._f.ref = {
@@ -282,15 +280,10 @@ function useController(props) {
282
280
  reportValidity: () => elm.reportValidity(),
283
281
  };
284
282
  }
285
- },
283
+ }, [name, control]),
286
284
  },
287
285
  formState,
288
- fieldState: {
289
- invalid: !!get(formState.errors, name),
290
- isDirty: !!get(formState.dirtyFields, name),
291
- isTouched: !!get(formState.touchedFields, name),
292
- error: get(formState.errors, name),
293
- },
286
+ fieldState: control.getFieldState(name, formState),
294
287
  };
295
288
  }
296
289
 
@@ -1189,7 +1182,7 @@ function createFormControl(props = {}) {
1189
1182
  _stateFlags.mount && _updateValid();
1190
1183
  }
1191
1184
  };
1192
- const updateTouchAndDirty = (name, fieldValue, isCurrentTouched, shouldRender = true) => {
1185
+ const updateTouchAndDirty = (name, fieldValue, isBlurEvent, shouldDirty, shouldRender) => {
1193
1186
  let isFieldDirty = false;
1194
1187
  const output = {
1195
1188
  name,
@@ -1200,7 +1193,7 @@ function createFormControl(props = {}) {
1200
1193
  _formState.isDirty = output.isDirty = _getDirty();
1201
1194
  isFieldDirty = isPreviousFormDirty !== output.isDirty;
1202
1195
  }
1203
- if (_proxyFormState.dirtyFields && !isCurrentTouched) {
1196
+ if (_proxyFormState.dirtyFields && (!isBlurEvent || shouldDirty)) {
1204
1197
  const isPreviousFieldDirty = get(_formState.dirtyFields, name);
1205
1198
  const isCurrentFieldPristine = deepEqual(get(_defaultValues, name), fieldValue);
1206
1199
  isCurrentFieldPristine
@@ -1211,13 +1204,13 @@ function createFormControl(props = {}) {
1211
1204
  isFieldDirty ||
1212
1205
  isPreviousFieldDirty !== get(_formState.dirtyFields, name);
1213
1206
  }
1214
- if (isCurrentTouched && !isPreviousFieldTouched) {
1215
- set(_formState.touchedFields, name, isCurrentTouched);
1207
+ if (isBlurEvent && !isPreviousFieldTouched) {
1208
+ set(_formState.touchedFields, name, isBlurEvent);
1216
1209
  output.touchedFields = _formState.touchedFields;
1217
1210
  isFieldDirty =
1218
1211
  isFieldDirty ||
1219
1212
  (_proxyFormState.touchedFields &&
1220
- isPreviousFieldTouched !== isCurrentTouched);
1213
+ isPreviousFieldTouched !== isBlurEvent);
1221
1214
  }
1222
1215
  isFieldDirty && shouldRender && _subjects.state.next(output);
1223
1216
  return isFieldDirty ? output : {};
@@ -1361,7 +1354,7 @@ function createFormControl(props = {}) {
1361
1354
  }
1362
1355
  }
1363
1356
  (options.shouldDirty || options.shouldTouch) &&
1364
- updateTouchAndDirty(name, fieldValue, options.shouldTouch);
1357
+ updateTouchAndDirty(name, fieldValue, options.shouldTouch, options.shouldDirty, true);
1365
1358
  options.shouldValidate && trigger(name);
1366
1359
  };
1367
1360
  const setValues = (name, value, options) => {
@@ -1380,7 +1373,8 @@ function createFormControl(props = {}) {
1380
1373
  const setValue = (name, value, options = {}) => {
1381
1374
  const field = get(_fields, name);
1382
1375
  const isFieldArray = _names.array.has(name);
1383
- set(_formValues, name, value);
1376
+ const cloneValue = cloneObject(value);
1377
+ set(_formValues, name, cloneValue);
1384
1378
  if (isFieldArray) {
1385
1379
  _subjects.array.next({
1386
1380
  name,
@@ -1392,14 +1386,14 @@ function createFormControl(props = {}) {
1392
1386
  _subjects.state.next({
1393
1387
  name,
1394
1388
  dirtyFields: _formState.dirtyFields,
1395
- isDirty: _getDirty(name, value),
1389
+ isDirty: _getDirty(name, cloneValue),
1396
1390
  });
1397
1391
  }
1398
1392
  }
1399
1393
  else {
1400
- field && !field._f && !isNullOrUndefined(value)
1401
- ? setValues(name, value, options)
1402
- : setFieldValue(name, value, options);
1394
+ field && !field._f && !isNullOrUndefined(cloneValue)
1395
+ ? setValues(name, cloneValue, options)
1396
+ : setFieldValue(name, cloneValue, options);
1403
1397
  }
1404
1398
  isWatched(name, _names) && _subjects.state.next({});
1405
1399
  _subjects.watch.next({
@@ -1423,13 +1417,13 @@ function createFormControl(props = {}) {
1423
1417
  !field._f.deps) ||
1424
1418
  skipValidation(isBlurEvent, get(_formState.touchedFields, name), _formState.isSubmitted, validationModeAfterSubmit, validationModeBeforeSubmit);
1425
1419
  const watched = isWatched(name, _names, isBlurEvent);
1420
+ set(_formValues, name, fieldValue);
1426
1421
  if (isBlurEvent) {
1427
1422
  field._f.onBlur && field._f.onBlur(event);
1428
1423
  }
1429
1424
  else if (field._f.onChange) {
1430
1425
  field._f.onChange(event);
1431
1426
  }
1432
- set(_formValues, name, fieldValue);
1433
1427
  const fieldState = updateTouchAndDirty(name, fieldValue, isBlurEvent, false);
1434
1428
  const shouldRender = !isEmptyObject(fieldState) || watched;
1435
1429
  !isBlurEvent &&
@@ -1504,6 +1498,12 @@ function createFormControl(props = {}) {
1504
1498
  ? get(values, fieldNames)
1505
1499
  : fieldNames.map((name) => get(values, name));
1506
1500
  };
1501
+ const getFieldState = (name, formState) => ({
1502
+ invalid: !!get((formState || _formState).errors, name),
1503
+ isDirty: !!get((formState || _formState).dirtyFields, name),
1504
+ isTouched: !!get((formState || _formState).touchedFields, name),
1505
+ error: get((formState || _formState).errors, name),
1506
+ });
1507
1507
  const clearErrors = (name) => {
1508
1508
  name
1509
1509
  ? convertToArrayPayload(name).forEach((inputName) => unset(_formState.errors, inputName))
@@ -1659,27 +1659,29 @@ function createFormControl(props = {}) {
1659
1659
  }
1660
1660
  };
1661
1661
  const resetField = (name, options = {}) => {
1662
- if (isUndefined(options.defaultValue)) {
1663
- setValue(name, get(_defaultValues, name));
1664
- }
1665
- else {
1666
- setValue(name, options.defaultValue);
1667
- set(_defaultValues, name, options.defaultValue);
1668
- }
1669
- if (!options.keepTouched) {
1670
- unset(_formState.touchedFields, name);
1671
- }
1672
- if (!options.keepDirty) {
1673
- unset(_formState.dirtyFields, name);
1674
- _formState.isDirty = options.defaultValue
1675
- ? _getDirty(name, get(_defaultValues, name))
1676
- : _getDirty();
1677
- }
1678
- if (!options.keepError) {
1679
- unset(_formState.errors, name);
1680
- _proxyFormState.isValid && _updateValid();
1662
+ if (get(_fields, name)) {
1663
+ if (isUndefined(options.defaultValue)) {
1664
+ setValue(name, get(_defaultValues, name));
1665
+ }
1666
+ else {
1667
+ setValue(name, options.defaultValue);
1668
+ set(_defaultValues, name, options.defaultValue);
1669
+ }
1670
+ if (!options.keepTouched) {
1671
+ unset(_formState.touchedFields, name);
1672
+ }
1673
+ if (!options.keepDirty) {
1674
+ unset(_formState.dirtyFields, name);
1675
+ _formState.isDirty = options.defaultValue
1676
+ ? _getDirty(name, get(_defaultValues, name))
1677
+ : _getDirty();
1678
+ }
1679
+ if (!options.keepError) {
1680
+ unset(_formState.errors, name);
1681
+ _proxyFormState.isValid && _updateValid();
1682
+ }
1683
+ _subjects.state.next(Object.assign({}, _formState));
1681
1684
  }
1682
- _subjects.state.next(Object.assign({}, _formState));
1683
1685
  };
1684
1686
  const reset = (formValues, keepStateOptions = {}) => {
1685
1687
  const updatedValues = formValues || _defaultValues;
@@ -1766,6 +1768,7 @@ function createFormControl(props = {}) {
1766
1768
  control: {
1767
1769
  register,
1768
1770
  unregister,
1771
+ getFieldState,
1769
1772
  _executeSchema,
1770
1773
  _getWatch,
1771
1774
  _getDirty,
@@ -1830,6 +1833,7 @@ function createFormControl(props = {}) {
1830
1833
  unregister,
1831
1834
  setError,
1832
1835
  setFocus,
1836
+ getFieldState,
1833
1837
  };
1834
1838
  }
1835
1839