DEV Community

Cover image for 🚫😩 An array of react refs

🚫😩 An array of react refs

ajsharp profile image Alex Sharp 🛠 Originally published at Updated on ・1 min read

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.

Discussion (7)

Editor guide
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) }}>

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: