Home > Mobile >  Using single ref for multiple input fields in react typescript
Using single ref for multiple input fields in react typescript

Time:12-05

I am trying to use the same ref for multiple input fields in for my form. But on logging it, the ref refers only to the first input field. Is there anyway I can use the same ref and use for different inputs?

import React, {FC, useEffect, useRef, useState} from 'react';
import { IFormProps } from '../../utils/Interfaces';
import 'react-phone-number-input/style.css'

const Form:FC<IFormProps> = ({formData, handleFormData, errors, handleValidate}) => {
  const inputField = React.useRef() as React.MutableRefObject<HTMLInputElement>;
  
  return (
    <form className='user-form'>
        <label>First Name</label>
        <input 
          type="text" 
          ref = {inputField}
          value={formData.firstName} 
          name="firstName" id="firstName" 
          onChange={(e) => handleFormData(e)} placeholder="Enter your first name"
          onFocus={() => console.log('focus')} 
          onBlur={() => handleValidate(inputField)}
          />
        <label>Last Name</label>
        <input 
            type="text" 
            value={formData.lastName} 
            name="lastName" id="lastName" 
            onChange={(e) => handleFormData(e)} 
            placeholder="Enter the last name"
            onBlur={() => handleValidate(inputField)}
            ref = {inputField}
        />
    </form>

  )
}

export default Form;

I am passing this information to the parent to handle validation. I am not sure how I can pass the same ref(inputField) as different input elements with its attributes.

I have tried doing this Use a single ref object across multiple input elements, but there is an error saying the following. I am aware its cause of typescript. But not sure how to handle it.

ref = {(el) => (inputField.current["firstName"] = el)}

Element implicitly has an 'any' type because expression of type '"firstName"' can't be used to index type 'HTMLInputElement'.
  Property 'firstName' does not exist on type 'HTMLInputElement'.

CodePudding user response:

Can define an array of ref and assign values by index

  const inputField = React.useRef<HTMLInputElement[]>([])

 <input 
      type="text" 
        ref={el => inputField.current[0] = el} 
      value={formData.firstName} 
      name="firstName" id="firstName" 
      onChange={(e) => handleFormData(e)} placeholder="Enter your first name"
      onFocus={() => console.log('focus')} 
      onBlur={() => handleValidate(inputField)}
      />
    <label>Last Name</label>
    <input 
        type="text" 
        value={formData.lastName} 
        name="lastName" id="lastName" 
        onChange={(e) => handleFormData(e)} 
        placeholder="Enter the last name"
        onBlur={() => handleValidate(inputField)}
        ref={el => inputField.current[1] = el} 
    />

CodePudding user response:

In typescript, most hooks are generic. You declare their type using <>. If you want to assign to properties firstName and lastName then declare them in your type. You will also need to initialize the object.

  const inputField = React.useRef<{
    firstName: HTMLInputElement;
    lastName: HTMLInputElement;
  }>({ firstName: null, lastName: null });

  return (
    <form className="user-form">
      <label>First Name</label>
      <input
        ref={(ref) => (inputField.current.firstName = ref)}
        ...
      />
      <label>Last Name</label>
      <input
        ref={(ref) => (inputField.current.lastName = ref)}
        ...
      />
    </form>
  );

demo: https://stackblitz.com/edit/react-ts-zkc3nj?file=App.tsx

  • Related