Reputation: 6511
I'm trying to use a ref in React, which is an array that contains references to multiple other divs in the DOM.
In a useEffect, I map through an object to render the divs, and I assign a ref to each div. Before assigning the ref, I instantiate a slot for it with createRef
.
I'm essentially trying to replicate what this answer has suggested doing.
The issue that I'm running into is that my compiler keeps seeing undefined
. I'm not sure why this is happening, but here is the code that I have:
import React from "react";
const items = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]
];
export default function Component() {
const [renderedItems, setRenderedItems] = React.useState();
const [height, setHeight] = React.useState(0);
const refsArray = React.useRef([]);
React.useEffect(() => {
const heightOfFirstDiv = refsArray.current[0].offsetHeight;
console.log("heightOfFirstDiv", heightOfFirstDiv); // <-- this is always undefined
setHeight(heightOfFirstDiv);
}, [renderedItems]);
React.useEffect(() => {
setRenderedItems(
items.map((item, index) => {
refsArray.current[index] = React.createRef();
return (
<div
ref={refsArray.current[index]}
style={{ height: 100, width: 40 }}
>
{item}
</div>
);
})
);
}, []);
return (
<div>
The height is: {height || "undefined"}
{renderedItems}
</div>
);
}
What am I doing wrong here?
Upvotes: 0
Views: 1125
Reputation: 46
The second answer to the question you have linked is better and simpler, actually. This can be implemented via callback refs:
import React from "react";
const items = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10]
];
export default function Component() {
const [height, setHeight] = React.useState(0);
const refsArray = React.useRef([]);
React.useEffect(() => {
const heightOfFirstDiv = refsArray.current[0].offsetHeight;
console.log("heightOfFirstDiv", heightOfFirstDiv);
setHeight(heightOfFirstDiv);
}, [renderedItems]);
const renderedItems = items.map((item, index) => (
<div
ref={(el) => (refsArray.current[index] = el)}
key={index}
style={{ height: 100, width: 40 }}
>
{item}
</div>
));
return (
<div>
The height is: {height || "undefined"}
{renderedItems}
</div>
);
}
Storing rendered elements in component state is not a good practice, as it makes components complicated, confusing and hard to debug.
Upvotes: 2
Reputation: 125
That's because your current[0] is in fact an object with a .current key inside it, you can get the value you want by simply editing your heightOfFirstDiv to show that key
const heightOfFirstDiv = refsArray.current[0].current.offsetHeight;
If you notice, on the example you tried to replicate you'll see they destructured this .current key, that's where the mistake came from
Upvotes: 1