[英]Generate multiple refs in map loop
I am still confused if I use useRef([]);
如果我使用
useRef([]);
我仍然感到困惑the right way, as itemsRef
returns Object {current: Array[0]}
.正确的方法,因为
itemsRef
返回Object {current: Array[0]}
。 Here in action: https://codesandbox.io/s/zealous-platform-95qim?file=/src/App.js:0-1157在这里行动: https://codesandbox.io/s/zealous-platform-95qim?file=/src/App.js:0-1157
import React, { useRef } from "react";
import "./styles.css";
export default function App() {
const items = [
{
id: "asdf2",
city: "Berlin",
condition: [
{
id: "AF8Qgpj",
weather: "Sun",
activity: "Outside"
}
]
},
{
id: "zfsfj",
city: "London",
condition: [
{
id: "zR8Qgpj",
weather: "Rain",
activity: "Inside"
}
]
}
];
const itemsRef = useRef([]);
// Object {current: Array[0]}
// Why? Isn't it supposed to be filled with my refs (condition.id)
console.log(itemsRef);
return (
<>
{items.map(cities => (
<div key={cities.id}>
<b>{cities.city}</b>
<br />
{cities.condition.map(condition => (
<div
key={condition.id}
ref={el => (itemsRef.current[condition.id] = el)}
>
Weather: {condition.weather}
<br />
Activity: {condition.activity}
</div>
))}
<br />
<br />
</div>
))}
</>
);
}
In the original example I receive // Object {current: Array[3]}
when I console.log(itemsRef);
在原始示例中,当我
console.log(itemsRef);
时收到// Object {current: Array[3]}
The difference is that I used in my version itemsRef.current[condition.id]
as its a nested map loop and therefore i
doesn't work.不同之处在于我在我的版本
itemsRef.current[condition.id]
中使用它作为嵌套的 map 循环,因此i
不起作用。
import React, { useRef } from "react";
import "./styles.css";
export default function App() {
const items = ["sun", "flower", "house"];
const itemsRef = useRef([]);
// Object {current: Array[3]}
console.log(itemsRef);
return items.map((item, i) => (
<div key={i} ref={el => (itemsRef.current[i] = el)}>
{item}
</div>
));
}
You're using non-numeric string keys when adding the refs
to itemRefs
, which means they end up being properties of the array object, but not array elements , so its length remains 0
.在将
refs
添加到itemRefs
时,您使用的是非数字字符串键,这意味着它们最终成为数组 object 的属性,但不是数组元素,因此它的长度保持0
。 Depending on your console, it may or may not show non-element properties on an array object.根据您的控制台,它可能会或可能不会在数组 object 上显示非元素属性。
You could make them array elements instead by using the index
from map
(but keep reading:):您可以使用
map
中的index
将它们设为数组元素(但请继续阅读:):
{cities.condition.map((condition, index) => (
<div
key={condition.id}
ref={el => (itemsRef.current[index] = el)}
>
Weather: {condition.weather}
<br />
Activity: {condition.activity}
</div>
))}
but depending on what you're doing with those refs I would avoid that in favor of making each condition
its own component instead:但是根据您对这些参考的处理方式,我会避免这种情况,而是将每个
condition
作为其自己的组件:
const Condition = ({weather, activity}) => {
const itemRef = useRef(null);
return (
<div
ref={itemRef}
>
Weather: {weather}
<br />
Activity: {activity}
</div>
);
};
Then get rid of itemRefs
and do:然后摆脱
itemRefs
并执行以下操作:
{cities.condition.map(({id, weather, activity}) => (
<Condition key={id} weather={weather} activity={activity} />
))}
One problem with your current way even if we use array elements is that itemRefs
will continue to have three elements in it even when the DOM elements that they used to refer to are gone (they'll have null
instead), since React calls your ref
callback with null
when the element is removed, and your code is just storing that null
in the array.即使我们使用数组元素,您当前方式的一个问题是
itemRefs
将继续在其中包含三个元素,即使它们过去引用的 DOM 元素已经消失(它们将具有null
代替),因为 React 调用您的ref
删除元素时使用null
回调,并且您的代码只是将该null
存储在数组中。
Alternatively, you might use an object:或者,您可以使用 object:
const itemRefs = useRef({});
// ...
{cities.condition.map(condition => (
<div
key={condition.id}
ref={el => {
if (el) {
itemsRef.current[condition.id] = el;
} else {
delete itemsRef.current[condition.id];
}
}}
>
Weather: {condition.weather}
<br />
Activity: {condition.activity}
</div>
))}
Or perhaps a Map
:或者也许是
Map
:
const itemRefs = useRef(new Map());
// ...
{cities.condition.map(condition => (
<div
key={condition.id}
ref={el => {
if (el) {
itemsRef.current.set(condition.id, el);
} else {
itemsRef.current.delete(condition.id);
}
}}
>
Weather: {condition.weather}
<br />
Activity: {condition.activity}
</div>
))}
But again, I'd lean toward making a Condition
component that manages its own ref.但同样,我倾向于制作一个
Condition
组件来管理它自己的 ref。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.