snippetjavascriptreactCritical
How can I use multiple refs for an array of elements with hooks?
Viewed 0 times
hooksmultipleuserefswithforelementscanhowarray
Problem
As far as I understood I can use refs for a single element like this:
How can I implement this for an array of elements? Obviously not like that: (I knew it even I did not try it:)
I have seen this and hence this. But, I'm still confused about how to implement that suggestion for this simple case.
const { useRef, useState, useEffect } = React;
const App = () => {
const elRef = useRef();
const [elWidth, setElWidth] = useState();
useEffect(() => {
setElWidth(elRef.current.offsetWidth);
}, []);
return (
Width is: {elWidth}
);
};
ReactDOM.render(
,
document.getElementById("root")
);
How can I implement this for an array of elements? Obviously not like that: (I knew it even I did not try it:)
const { useRef, useState, useEffect } = React;
const App = () => {
const elRef = useRef();
const [elWidth, setElWidth] = useState();
useEffect(() => {
setElWidth(elRef.current.offsetWidth);
}, []);
return (
{[1, 2, 3].map(el => (
Width is: {elWidth}
))}
);
};
ReactDOM.render(
,
document.getElementById("root")
);
I have seen this and hence this. But, I'm still confused about how to implement that suggestion for this simple case.
Solution
A ref is initially just
There should be an array of refs at some point. In case the array length may vary between renders, an array should scale accordingly:
This piece of code can be optimized by unwrapping
{ current: null } object. useRef keeps the reference to this object between component renders. current value is primarily intended for component refs but can hold anything.There should be an array of refs at some point. In case the array length may vary between renders, an array should scale accordingly:
const arrLength = arr.length;
const [elRefs, setElRefs] = React.useState([]);
React.useEffect(() => {
// add or remove refs
setElRefs((elRefs) =>
Array(arrLength)
.fill()
.map((_, i) => elRefs[i] || createRef()),
);
}, [arrLength]);
return (
{arr.map((el, i) => (
...
))}
);
This piece of code can be optimized by unwrapping
useEffect and replacing useState with useRef but it should be noted that doing side effects in render function is generally considered a bad practice:const arrLength = arr.length;
const elRefs = React.useRef([]);
if (elRefs.current.length !== arrLength) {
// add or remove refs
elRefs.current = Array(arrLength)
.fill()
.map((_, i) => elRefs.current[i] || createRef());
}
return (
{arr.map((el, i) => (
...
))}
);
Context
Stack Overflow Q#54633690, score: 174
Revisions (0)
No revisions yet.