Talya Sterman
Talya Sterman

Reputation: 215

use one useRef for multiple elements

I Have a react component that is holding

const inputSchemaVersionRef =useRef<HTMLInputElement>();

The components has multiple text Fields and the ref is connected to each text Field like this:

inputRef={(ref) => (inputSchemaVersionRef.current = ref)}

(it is inputRef because MUI library). This works.

when I tried inputRef={inputSchemaVersionRef}, the ref was connected to the last instance of text field.

Can someone explain why it only refers to the last text field and why I need to assign the ref to the inputSchemaVersionRef current for it to work?

Upvotes: 3

Views: 2088

Answers (1)

mahooresorkh
mahooresorkh

Reputation: 1444

useRef returns a ref object with a single current property initially set to the initial value you provided (you can check it out in react documentation). That's just how it works. When you want to change the ref value, it is necessary to change the current property to keep the ref object reference in the memory.

As for the inputRef issue; It is because you have several text fields (as you said) and the ref is connected to each text field, so logically the value is replaced by each one of the text fields one by one till it gets to the last one and it stores in the ref. If you want to prevent that you can initialize inputSchemaVersionRef as an empty array like this (I assume that you have two text fields):

const inputSchemaVersionRef =useRef<HTMLInputElement[]>([]);

and connect text fields to the ref like :

<TextField
  id="myFirstTextField"
  inputRef={ref => {
    inputSchemaVersionRef.current[0] = ref
  }}
/>
<TextField
  id="mySecondTextField"
  inputRef={ref => {
    inputSchemaVersionRef.current[1] = ref
  }}
/>

Or you can initialize inputSchemaVersionRef as a json like this:

const inputSchemaVersionRef = useRef<{
    myFirstTextField:HTMLInputElement | null;
    mySecondTextField:HTMLInputElement | null
  }>({myFirstTextField:null, mySecondTextField: null});

and then use it like below:

<TextField
  id="myFirstTextField"
  inputRef={ref => {
    inputSchemaVersionRef.current.myFirstTextField = ref
  }}
/>

<TextField
  id="mySecondTextField"
  inputRef={ref => {
    inputSchemaVersionRef.current.mySecondTextField = ref
  }}
/>

So input ref values will never get overrided.

Upvotes: 4

Related Questions