简体   繁体   English

Map 子引用到父数组

[英]Map child refs into parent array

I attempting to map an array of children but to assign a ref to them as I do it so I can track their positions from in the parent.我试图 map 一个子数组,但在我这样做时为它们分配一个参考,这样我就可以从父级中跟踪它们的位置。

However, I need to store each ref in an array.但是,我需要将每个 ref 存储在一个数组中。

I've attempted the below, but I get a ref containing an array .我尝试了以下,但我得到了一个包含数组的 ref How could I modify it to get an array of refs ?我怎样才能修改它以获得一个refs 数组

This is so that I can track the element positions using a getBoundingClientRect() hook这样我就可以使用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>
          )
        })
      )}
    </>
  );
};

Create the refs first (same size as your array) and pass it to your component.首先创建 refs(与您的数组大小相同)并将其传递给您的组件。 I check the childrenLength because it may change between renders.我检查了 childrenLength,因为它可能会在渲染之间发生变化。

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>
          )
        })
      )}
    </>
  );
};

This should be easy这应该很容易

Here is an example how I would do it.这是我将如何做的一个例子。

 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> ) ) } </> ); };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM