#javascript #reactjs
Вопрос:
Я пытаюсь сопоставить массив дочерних элементов, но назначить им ссылку, когда я это делаю, чтобы я мог отслеживать их позиции в родительском элементе.
Однако мне нужно хранить каждую ссылку в массиве.
Я попытался сделать это ниже, но получил ссылку, содержащую массив. Как я мог бы изменить его, чтобы получить массив ссылок?
Это делается для того, чтобы я мог отслеживать позиции элементов с помощью getBoundingClientRect()
крючка
export default function ({ children }) => {
const itemsRef = useRef([]);
console.log(itemsRef);
// returns a ref containing an array
// {current: Array(5)}
// How could I modify what I am doing
// to to instead return an array of refs?
// something like:
// [{current: HTMLDivElement}, {current: HTMLDivElement}, .....]
return (
<>
{React.Children.map(children, (child, index) =>
React.cloneElement(child, {
ref: (ref) => (
<Item ref={(itemsRef.current[index] = ref)} key={index}>
{child}
</Item>
)
})
)}
</>
);
};
Комментарии:
1. Прочитайте это , сохраняя массив элементов с помощью крючка useRef
Ответ №1:
Сначала создайте ссылки (того же размера, что и ваш массив) и передайте их своему компоненту. Я проверяю длину детей, потому что она может меняться между рендерами.
export default function ({ children }) => {
const itemsRef = useRef([]);
const childrenLength = itemsRef;
if (itemsRef.current.length != childrenLength) {
itemsRef.current = Array(arrLength).fill().map((_, i) => itemsRef.current[i] || createRef());
}
return (
<>
{React.Children.map(children, (child, index) =>
React.cloneElement(child, {
ref: (ref) => (
<Item ref={itemsRef.current[index]} key={index}>
{child}
</Item>
)
})
)}
</>
);
};
Ответ №2:
Это должно быть легко
Вот пример того, как бы я это сделал.
export default function({children} : {children: React.ReactNode[]}) => {
const itemsRef = useRef([]);
console.log(itemsRef);
refLoaded = () => {
if (itemsRef.current.length == children.length) {
// all ref are loaded, do you work here
}
}
return (
<> {
children.map((child, index) => (
<Item ref = {(c) => {
if (c)
itemsRef.current[index] = c;
}
key = {
index
}
onLayout={refLoaded}>
{child}
</Item>
)
)
}
</>
);
};
Комментарии:
1. Я думаю, что вы отвечаете, имея в виду React Native. Это просто реакция
2. Это должно работать на обоих, это не имеет ничего общего только с react native. его машинопись и реакция
3. Возможно, onLayout является родным для react, вместо этого вы могли бы добавить refLoaded в разделе ref