将子引用映射到父数组

时间:2021-03-19 15:09:13

标签: javascript reactjs

我试图映射一个孩子的数组,但在我这样做时为他们分配了一个引用,这样我就可以从父级中跟踪他们的位置。

但是,我需要将每个 ref 存储在一个数组中。

我已经尝试了以下操作,但是我得到了一个 ref 包含一个数组。 我如何修改它以获得引用数组

这样我就可以使用 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>
          )
        })
      )}
    </>
  );
};

2 个答案:

答案 0 :(得分:0)

首先创建引用(与您的数组大小相同)并将其传递给您的组件。我检查了 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>
          )
        })
      )}
    </>
  );
};

答案 1 :(得分:0)

这应该很容易

这是我将如何做的一个例子。

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