Home > Enterprise >  can you use ref to reference different elements ? depending on some action in react?
can you use ref to reference different elements ? depending on some action in react?

Time:10-01

I want to be able to target the clicked btn using ref the problem is I always get the second one any idea to solve this issue ? and lets say i have a 1 native select element that has 2 optgroups and I want know from which optgroup the selection is coming ? can I use ref to my advantage in this case ?

let refData = useRef('');

    const handleClick = (e) => {
    console.log(refData.current);
    // Console log shows only the second btn even if i click on the first
    }

    <button ref={refData} label={'btn1'} onClick={handleClick}>
    1
    </button>

    <button ref={refData} label={'btn2'} onClick={handleClick}>
    2
    </button>

<NativeSelect  name='excercises' onChange={handleSelect}>
          <optgroup label={'opt1'} >
            {optionsA.map((option, index) => (
              <option key={option.id}>{option}</option>
            ))}
          </optgroup>
          <optgroup label={'opt2'} >
            {optionsB.map((option) => (
              <option key={option.id}>{option.supplment}</option>
            ))}
          </optgroup>
        </NativeSelect>

CodePudding user response:

can you use ref to reference different elements ? depending on some action in react?

Yes, but you probably don't need or want a ref for what you seem to be doing. It certainly won't tell you which button was clicked inside handleClick.

If you need to reference the button that was clicked in handleClick, you can do that via the event object:

const handleClick = (e) => {
    const btn = e.target.closest("button");
    // ...use `btn` here...
};

Live Example:

But, regarding the question in your title: You can only use a ref for one element at a time. So to use it for different elements based on a condition, keep track of which one you want the ref to refer to, and then either do or don't use it on that element when rendering.

For instance, let's say you have a state member (I'll call it whichButton) that contains "btn1" if you want the ref on btn1 and "btn2" if you want it on btn2:

<button ref={whichButton === "btn1" ? refData : undefined} label={'btn1'} onClick={handleClick}>
1
</button>

<button ref={whichButton === "btn2" ? refData : undefined} label={'btn2'} onClick={handleClick}>
2
</button>

Live Example:

CodePudding user response:

let refData1 = useRef('');
let refData2 = useRef('');

const handleClick = (e) => {
    console.log(refData.current);
}

<button ref={refData1} label={'btn1'} onClick={handleClick}>1</button>
<button ref={refData2} label={'btn2'} onClick={handleClick}>2</button>

CodePudding user response:

You don't really need to use ref. Try this:

const handleClick = (e) => {
    console.log(e.target.name);
};

And define your buttons like this:

<button name='btn1' onClick={handleClick}>1</button>

<button name='btn2' onClick={handleClick}>2</button>

CodePudding user response:

You have to use an array:

let refData = useRef([]);

An set an ref by this way:

ref={el => itemsRef.current[0] = el} 

For second element:

ref={el => itemsRef.current[1] = el} 

Then, you can access all of these elements, by single refData.

However, this will be better way for you:

const handleClick = e => {
  console.log(e.target);
}

Using e.target property, you don't have to define refs.

  • Related