-1

In React, the useRef function returns an object with the argument stored under the key current. Sometimes I'd like to use an array, e.g. to keep a list of references, like

const divsRef = useRef([]);
return Array.from({ length: n }, (_, i) => (
  <div
    ref={function (el) {
      divsRef.current[i] = el;
    }}
  />
));

but typing out current all the time is cumbersome. If I do

const divsRef = useRef();
return Array.from({ length: n }, (_, i) => (
  <div
    ref={function (el) {
      divsRef[i] = el;
    }}
  />
));

instead, then the resulting object isn't iterable. Hence my question, is there an easy way to turn an object into an iterable array, without changing its identity (otherwise the object wouldn't persist between rerenders)? I got it iterable by doing Object.setPrototypeOf(divsRef, Object.getPrototypeOf([])) but then [...divsRef] always returns the empty array.

fweth
  • 631
  • 6
  • 16
  • "but typing out `current` all the time is cumbersome": Welcome to programming. You'll get used to it. – jsejcksn Sep 18 '22 at 13:22
  • I don't get it: why is it "cumbersome" to type out current? It's like saying it's cumbersome to use `Array.from()` and you just want `Array()` – Terry Sep 18 '22 at 13:27
  • People on IRC told me that `Array()` is bad, so IDK. But I'm not talking about typing it out in the snippet I posted here, I meant typing it out whenever I want to access the ref. All that `useRef` is doing, basically, is to create an object and returning it back in each rerender. It should be agnostic about the shape of the object (it actually is, it just creates the `current` property on its first call). – fweth Sep 18 '22 at 13:29

1 Answers1

1

If you don’t need the actual ref for anything other than to access and use the array at its .current property, then you can use this syntax to avoid the repeated typing of that property name:

const {current: divArray} = useRef([]);
// divArray.push(div);
// etc…

And if you do, then just destructure it on a separate line:

const divsRef = useRef([]);
const {current: divArray} = divsRef;
jsejcksn
  • 27,667
  • 4
  • 38
  • 62