react-hook-form: issue: Uncaught TypeError: fieldRef.focus is not a function error in React-hook-form setFocus with Reactstrap Input

Version Number

7.36.1

Codesandbox/Expo snack

https://codesandbox.io/s/gallant-voice-vqqi47?file=/src/App.js

Steps to reproduce

  1. In the sandbox, don’t fill up anything and just click submit.

More details in my stackoverflow question: https://stackoverflow.com/questions/73931883/uncaught-typeerror-fieldref-focus-is-not-a-function-error-in-react-hook-form-se

Expected behaviour

Supposedly, I want it to focus to the first input that errors but it crashes instead.

What browsers are you seeing the problem on?

Chrome

Relevant log output

react-dom.development.js:22839 Uncaught TypeError: fieldRef.focus is not a function
    at setFocus (createFormControl.ts:1226:1)
    at usePersonalAccountForm.ts:73:1
    at commitHookEffectListMount (react-dom.development.js:23150:1)
    at commitPassiveMountOnFiber (react-dom.development.js:24926:1)
    at commitPassiveMountEffects_complete (react-dom.development.js:24891:1)
    at commitPassiveMountEffects_begin (react-dom.development.js:24878:1)
    at commitPassiveMountEffects (react-dom.development.js:24866:1)
    at flushPassiveEffectsImpl (react-dom.development.js:27039:1)
    at flushPassiveEffects (react-dom.development.js:26984:1)
    at commitRootImpl (react-dom.development.js:26935:1)
setFocus @ createFormControl.ts:1226
(anonymous) @ usePersonalAccountForm.ts:73
commitHookEffectListMount @ react-dom.development.js:23150
commitPassiveMountOnFiber @ react-dom.development.js:24926
commitPassiveMountEffects_complete @ react-dom.development.js:24891
commitPassiveMountEffects_begin @ react-dom.development.js:24878
commitPassiveMountEffects @ react-dom.development.js:24866
flushPassiveEffectsImpl @ react-dom.development.js:27039
flushPassiveEffects @ react-dom.development.js:26984
commitRootImpl @ react-dom.development.js:26935
commitRoot @ react-dom.development.js:26682
performSyncWorkOnRoot @ react-dom.development.js:26117
flushSyncCallbacks @ react-dom.development.js:12042
(anonymous) @ react-dom.development.js:25651
react_devtools_backend.js:4026 The above error occurred in the <PersonalAccountPage> component:

    at PersonalAccountPage (https://localhost:3000/static/js/src_pages_CreateAccount_PersonalAccount_PersonalAccountPage_tsx.chunk.js:130:81)
    at RenderedRoute (https://localhost:3000/static/js/bundle.js:61948:5)
    at Outlet (https://localhost:3000/static/js/bundle.js:62303:26)
    at Suspense
    at RouteWrapper (https://localhost:3000/static/js/bundle.js:1649:81)
    at RenderedRoute (https://localhost:3000/static/js/bundle.js:61948:5)
    at Routes (https://localhost:3000/static/js/bundle.js:62397:5)
    at div
    at div
    at CreateAccountRoutes
    at RenderedRoute (https://localhost:3000/static/js/bundle.js:61948:5)
    at Outlet (https://localhost:3000/static/js/bundle.js:62303:26)
    at Suspense
    at RouteWrapper (https://localhost:3000/static/js/bundle.js:1649:81)
    at RenderedRoute (https://localhost:3000/static/js/bundle.js:61948:5)
    at Routes (https://localhost:3000/static/js/bundle.js:62397:5)
    at main
    at Layout (https://localhost:3000/static/js/bundle.js:2033:5)
    at Router (https://localhost:3000/static/js/bundle.js:62328:15)
    at BrowserRouter (https://localhost:3000/static/js/bundle.js:60549:5)
    at div
    at App (https://localhost:3000/static/js/bundle.js:1347:51)
    at Provider (https://localhost:3000/static/js/bundle.js:57681:5)
    at r (https://localhost:3000/static/js/bundle.js:56945:19)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
overrideMethod @ react_devtools_backend.js:4026
logCapturedError @ react-dom.development.js:18687
update.callback @ react-dom.development.js:18720
callCallback @ react-dom.development.js:13923
commitUpdateQueue @ react-dom.development.js:13944
commitLayoutEffectOnFiber @ react-dom.development.js:23391
commitLayoutMountEffects_complete @ react-dom.development.js:24688
commitLayoutEffects_begin @ react-dom.development.js:24674
commitLayoutEffects @ react-dom.development.js:24612
commitRootImpl @ react-dom.development.js:26823
commitRoot @ react-dom.development.js:26682
performSyncWorkOnRoot @ react-dom.development.js:26117
flushSyncCallbacks @ react-dom.development.js:12042
(anonymous) @ react-dom.development.js:25651
react-dom.development.js:12056 Uncaught TypeError: fieldRef.focus is not a function
    at setFocus (createFormControl.ts:1226:1)
    at usePersonalAccountForm.ts:73:1
    at commitHookEffectListMount (react-dom.development.js:23150:1)
    at commitPassiveMountOnFiber (react-dom.development.js:24926:1)
    at commitPassiveMountEffects_complete (react-dom.development.js:24891:1)
    at commitPassiveMountEffects_begin (react-dom.development.js:24878:1)
    at commitPassiveMountEffects (react-dom.development.js:24866:1)
    at flushPassiveEffectsImpl (react-dom.development.js:27039:1)
    at flushPassiveEffects (react-dom.development.js:26984:1)
    at commitRootImpl (react-dom.development.js:26935:1)

Code of Conduct

  • I agree to follow this project’s Code of Conduct

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 26 (9 by maintainers)

Commits related to this issue

Most upvoted comments

The issue is still there on version “react-hook-form”: “^7.39.4”,

Tried to pass error to Cleave components or Flatpickr and everytime an error is generated the focus method crashes the app giving this error:

Env

  • Operating System version: MacOS 13.0.1 (22A400)
  • Browser version: Chrome Version 107.0.5304.110 (Official Build) (arm64)
react-dom.development.js:22839 Uncaught TypeError: elm.focus is not a function
    at Object.focus (useController.ts:132:30)
    at focusFieldBy (focusFieldBy.ts:18:18)
    at Object._focusError (createFormControl.ts:1042:5)
    at useForm.ts:103:38
    at commitHookEffectListMount (react-dom.development.js:23150:26)
    at commitPassiveMountOnFiber (react-dom.development.js:24926:13)
    at commitPassiveMountEffects_complete (react-dom.development.js:24891:9)
    at commitPassiveMountEffects_begin (react-dom.development.js:24878:7)
    at commitPassiveMountEffects (react-dom.development.js:24866:3)
    at flushPassiveEffectsImpl (react-dom.development.js:27039:3)
focus @ useController.ts:132
focusFieldBy @ focusFieldBy.ts:18
_focusError @ createFormControl.ts:1042
(anonymous) @ useForm.ts:103
commitHookEffectListMount @ react-dom.development.js:23150
commitPassiveMountOnFiber @ react-dom.development.js:24926
commitPassiveMountEffects_complete @ react-dom.development.js:24891
commitPassiveMountEffects_begin @ react-dom.development.js:24878
commitPassiveMountEffects @ react-dom.development.js:24866
flushPassiveEffectsImpl @ react-dom.development.js:27039
flushPassiveEffects @ react-dom.development.js:26984
commitRootImpl @ react-dom.development.js:26935
commitRoot @ react-dom.development.js:26682
performSyncWorkOnRoot @ react-dom.development.js:26117
flushSyncCallbacks @ react-dom.development.js:12042
(anonymous) @ react-dom.development.js:25651

Only if I set “shouldFocusError” to false everything work fine.

*** relevant code ***

  // ** Hooks
  const {
    reset,
    control,
    setValue,
    handleSubmit,
    formState: { errors, isValid }
  } = useForm({
    mode: 'onChange',
    resolver: yupResolver(ValidationSchema),
    shouldFocusError: true,
    defaultValues: {
      price: '',
      date: '',
    }
  })

Components


 <Col md="6" className="mb-1">
                <Label className="form-label" for="price">
                  {t('Expense Price')} <span className="text-danger">*</span>
                </Label>
                <Controller
                  id="price"
                  control={control}
                  name="price"
                  render={({ field }) => (
                    <Cleave
                      className="form-control"
                      options={{
                        numeral: true,
                        numeralDecimalMark: '.',
                        delimiter: ''
                      }}
                      placeholder="78.00"
                      invalid={errors.price}
                      {...field}
                    />
                  )}
                />
                {errors.price && (
                  <Alert color="danger" isOpen={true}>
                    <div className="alert-body">
                      <AlertCircle size={15} />{' '}
                      <span className="ms-1">{errors.price?.message}</span>
                    </div>
                  </Alert>
                )}
              </Col>
             <Col md="6" className="mb-1">
                <Label className="form-label" for="date">
                  {t('Expense Date')} <span className="text-danger">*</span>
                </Label>
                <Controller
                  control={control}
                  id="date"
                  name="date"
                  render={({ field }) => (
                    <Flatpickr
                      options={{
                        disableMobile: true, // TODO: disables the native mobile calendar
                        locale: {
                          firstDayOfWeek: 1 // start week on Monday
                        },
                        minDate: getFormattedDate(selectedPermit.start),
                        maxDate: getFormattedDate(selectedPermit.end)
                      }}
                      className={classnames('form-control', {
                        'is-invalid': errors.date
                      })}
                      {...field}
                    />
                  )}
                />
                {errors.date && (
                  <FormFeedback>{errors.date?.message}</FormFeedback>
                )}
           </Col>

This code works fine with me using controlled RHF, empty input doesn’t fire elm.focus error :

<div className="field">
              <span className="p-float-label">
                <Controller
                  name="OldPassword"
                  control={control}
                  render={({ field: { ref, ...field } }) => {
                    return (
                      <Password
                        id={field.name}
                        value={field.value}
                        onChange={field.onChange}
                        toggleMask
                        autoFocus
                        feedback={false}
                        className={classNames({
                          'p-invalid': formState?.errors?.OldPassword,
                        })}
                      />
                    )
                  }}
                />
                <label
                  htmlFor="OldPassword"
                  className={classNames({ 'p-error': errors.OldPassword })}
                >
                  Old Password*
                </label>
              </span>
              {getFormErrorMessage('OldPassword')}
</div>

working version: https://codesandbox.io/s/stupefied-mahavira-9s2ffl?file=/src/App.js

import { Controller, useForm } from "react-hook-form";
import Headers from "./Header";
import DatePicker from "react-datepicker";
import "./styles.css";

export default function App() {
  const { register, handleSubmit, control } = useForm();
  const onSubmit = (data) => console.log(data);

  return (
    <div>
      <Headers />

      <form onSubmit={handleSubmit(onSubmit)}>
        <input {...register("firstName")} placeholder="First Name" />
        <Controller
          name="test"
          control={control}
          rules={{
            required: true
          }}
          render={({ field }) => (
            <DatePicker
              selected={field.value}
              onChange={(date) => field.onChange(date)}
              ref={(ref) => {
                field.ref({
                  focus: ref.setFocus
                });
              }}
            />
          )}
        />
        <input type="submit" />
      </form>
    </div>
  );
}

If you remove strict mode, for now, it’s going to work otherwise you can wait for the next minor version release which should resolve this issue. see my commit above ^

hmmm not sure, if useImperativeHandle works for you then let’s keep it that way for now.

@bluebill1049 Big thanks 😊 it works.

looks like it’s related to strict mode, I will patch this issue.

Thanks for the issue report. This is not an issue related to hook form, however, the next minor release will prevent such run time error.

This issue is related to ref prop, please check your input reference to see if the actual dom element is supplied (which has focus method).

working version: https://codesandbox.io/s/charming-violet-vq2km1?file=/src/App.js