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