DEV Community

Cover image for 🚫😩 An array of react refs
Alex Sharp 🛠
Alex Sharp 🛠

Posted on • Updated on • Originally published at

🚫😩 An array of react refs

Apparently you can't store React refs in an array. For some reason they get wiped out, so if you need to store a collection of refs, you have to do something like this (forgive me lord, for I hath sinned):

import React from 'react'

const collection = ["label 1", "label 2"]

class SinFactory extends React.Component {
  constructor(props) {
    this.ref0 = React.createRef()
    this.ref1 = React.createRef()

  render() {
    return (
        {, i) => {
          return <div key={label} 
Enter fullscreen mode Exit fullscreen mode

It's truly filthy, but it works.

☝️ Be sure to check out Sharesecret, which makes it easy to securely share sensitive data.

Top comments (8)

amantel profile image

I tried just now, setting this.myRef = []; and using callbacks ref={(ref) => { this.myRef[someval] = ref; return true; }} - everything worked perfectly.

elramus profile image
Luke Ramus

Thanks, this was helpful. If anyone else out there wants to do this with TypeScript and hooks, this worked like a charm for me:

const tentRefs = useRef<(HTMLDivElement | null)[]>([])

<div className="name-tent" key={studentId} ref={(ref) => { tentRefs.current.push(ref) }}>

sunanda3055 profile image

It worked for me as well. This is really cool. I have never used ref in loop and was facing issues, but with your help it rocked. Thanks!!

paddy57 profile image
Pradnyanand Milind Pohare

hello, how can i access stored values in myRef, like say what if i want to access next myRef value on currnet myRef, what should i do there? myRef.nextItem ?

joostkiens profile image
Joost Kiens • Edited

How about using a combination of useRef and createRef?

const refs = useRef( => createRef())

return, i) => <div key={i} ref={refs.current[i]}>{x}</div>
Enter fullscreen mode Exit fullscreen mode

The first rule of hooks states we can't call hooks (useRef) in a loop, but we can call createRef in a loop.

The array of refs (from createRef) will not trigger renders and stay in place between renders because it's safely stored in the .current created by useRef.

Using this way, we don't need to know how many refs we need to create upfront and it's a bit less noise (perhaps at the price of a little less clarity). Any downsides with this?

iwi4a_24 profile image

I used callback refs by creating an empty array in the parent elementRefs = []; and then while iterating over the child components, I passed a function to the ref attribute ref={el => this.elementRefs[index] = el}. This way, it executes the function in the child, but it has elementRefs in its scope and add itself to the array. So at the end, you end up with an array elementRefs with all the ref elements in it.

amantel profile image

Really? I have a bunch (50+) of buttons to scroll to and I wanted to use refs for those. What a pain.

moaazbhnas profile image
Moaaz Bhnas

There's a solution with hooks: