如何对带有钩子的元素数组使用多个引用? [英] How can I use multiple refs for an array of elements with hooks?
问题描述
据我了解,我可以将refs用于单个元素,例如:
As far as I understood I can use refs for a single element like this:
const { useRef, useState, useEffect } = React;
const App = () => {
const elRef = useRef();
const [elWidth, setElWidth] = useState();
useEffect(() => {
setElWidth(elRef.current.offsetWidth);
}, []);
return (
<div>
<div ref={elRef} style={{ width: "100px" }}>
Width is: {elWidth}
</div>
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="root"></div>
如何为元素数组实现此功能?显然不是这样:(即使我没有尝试过,我也知道:)
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 (
<div>
{[1, 2, 3].map(el => (
<div ref={elRef} style={{ width: `${el * 100}px` }}>
Width is: {elWidth}
</div>
))}
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById("root")
);
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="root"></div>
我见过此,因此也见过
I have seen this and hence this. But, I'm still confused about how to implement that suggestion for this simple case.
推荐答案
ref最初只是{ current: null }
对象. useRef
在组件渲染之间保留对此对象的引用. current
值主要用于组件引用,但可以容纳任何内容.
A ref is initially just { 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 (
<div>
{arr.map((el, i) => (
<div ref={elRefs[i]} style={...}>...</div>
))}
</div>
);
可以通过展开useEffect
并将useState
替换为useRef
来优化这段代码,但应注意,在渲染函数中产生副作用通常被认为是一种不好的做法:
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 (
<div>
{arr.map((el, i) => (
<div ref={elRefs.current[i]} style={...}>...</div>
))}
</div>
);
这篇关于如何对带有钩子的元素数组使用多个引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!