reactjsreact-hook-form

How to set focus when using React hook form Controller component


I have a CustomTextBox component that is wrapped in react-hook-form Controller component and all works fine including validation and displaying the error message with ErrorMessage component.

The only thing left to-do is to setFocus on the fields when there is errors in the form. This is my first TypeScript project and i'm struggling to find solutions which are similar to mine.

I tried useRef but this only give compile time error =>

"Property 'ref' does not exist on type 'IntrinsicAttributes".

Below is my Custom component. Please guys all help will be appreciated. Thanks in advance

import React, { useRef } from "react";
import TextField from '@material-ui/core/TextField';
import { Control, Controller } from "react-hook-form";
import { Keys } from '../Profile/interfaces';

interface Props {
  id: string;
  label: string,
  variant: "filled" | "standard" | "outlined", 
  disabled?: boolean,
  control: Control<any,any>
  required?: boolean,
  name: Keys,
  requiredMsg?: string
}

const CustomTextBox: React.FC<Props> = ({id, label, variant,disabled=false, control, 
required=false, name, requiredMsg}) => {
  const inputRef = useRef<React.RefObject<HTMLButtonElement>>();
  return (
    <Controller        
      ref={inputRef}
      name={name}      
      control={control}
      rules={{required: required ? requiredMsg : null}}     
      render={({ field }) =>
        <TextField inputRef={field.ref}  InputLabelProps={{ shrink: true }} id={id} label={label} variant={variant} 
         disabled={disabled} {...field}
        style={{marginTop: '10px', marginBottom: '10px', minWidth: '250px'}} /> }
    />
  );
}

export default CustomTextBox;

Solution

  • So thanks to @Victor Luft i was able to get it right with the below code. Also this is not in the component itself but rather on the page/component that uses Custom Components. This will focus on any element that has an error in your react-hook-form form tag. I hope that makes sense.

    Thanks again Victor

    useEffect(() => {               
            const firstErrorKey = Object.keys(errors).find((key) => errors[key]);
        if (firstErrorKey) {
          (document.querySelector(
            `input[name="${firstErrorKey}"]`
          ) as HTMLInputElement | null)?.focus();
        }
      }, [Object.keys(errors)]);