Im trying to have a dynamic array of references. These references would come from the Grid items, that are being mapped from a list to the Grid Layout-Element.
This is my code:
<GridLayout layout = {layout} onLayoutChange={(currentLayout) => {onLayoutChange(currentLayout)}} onDragStop={currentLayout => onDragStop(currentLayout)} onDropDragOver={onDropDragOver} onDrop={(currentLayout,item,_event) => onDrop(item,_event)} onResizeStart={(layout, oldItem, newItem, placeholder, event, element) => {setConfigValues(oldItem.i)}} onResize={(layout, oldItem, newItem, placeholder, event, element) => onResize(oldItem)} style={canvasBoxStyle} ref={gridRef} {...gridLayoutProps} > {layout.map((layoutElement) => <div style={{zIndex:getAttributesById(layoutElement.i).attributes.zIndex}} key={parseInt(layoutElement.i)} data-grid={layoutElement} ref={(ref) => elementRefs.current.push(ref)} onClick={() => {setConfigValues(layoutElement.i)}} > {createElement(layoutElement)} </div> )} </GridLayout>
It seems like the “ref”-attribute gets ignored from react, because none of the grid items refs are being pushed into the refs-array
const elementRefs = useRef([]);
The ref-attribute works just fine for the “GirdLayout”-Element.
I dont know what im doing wrong i tried many stuff. I need the refs of each grid item to get the width and height of each of them.
Advertisement
Answer
I think pushing the ref for every component render is not a good idea because that could create a big array with repeated elements in case of re-renders.
You could solve this problem by creating some sort of map of refs. For instance, the following code works fine for me:
import React, { useRef, useEffect } from "react"; const data = ["a", "b", "c", "d"]; export default function App() { const refs = useRef([]); useEffect(() => { console.log(refs); }, []); return ( <div className="App"> {data.map((d, i) => ( <p key={i} ref={(ref) => (refs.current[i] = ref)}> {d} </p> ))} </div> ); }
That answer is based on other answer from Jorge Pirela: https://stackoverflow.com/a/70885503/7159312
May not be the most optimal way of doing that.