动态添加项目到数组

Dynamically adding items to an array

我在向数组中添加项目时遇到问题。我想获取页面上 <p> 个元素的高度并将它们添加到数组中。但是每次它得到一个只有一个元素的数组时,它看起来就像在重置之前的值。

const Paragraph = () => {
  const [height, setHeight] = useState(0);
  const [arrayWithHeight, setArrayWithHeight] = useState([]);

  const ref = useRef(null);

  useEffect(() => {
    setHeight(ref.current.clientHeight);
    addItemsToArray(ref.current.clientHeight);
  }, [addItemsToArray]);



  function addItemsToArray(height) {
    setArrayWithHeight(heights => [...heights, height]);
  }

  console.log('arrayWithHeight', arrayWithHeight)

  return (
   <div>
      <p ref={ref}>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
      <p ref={ref}>Lorem ipsum dolor sit amet</p>
      <p ref={ref}>Lorem</p>
    </div>

  );
};

导出默认段落; 输出示例:[113]、[124]、[55]。但是,我想收到一个 table [113,124,55]。你知道问题出在哪里吗?

arrayWithHeight 数组在每个渲染周期都被重新声明,并且只有一个值被推入其中。将 arrayWithHeight 转换为本地组件状态并使用功能状态更新来保留以前的状态值。

React 状态更新也是异步处理的,因此尝试使用 height 状态添加到 arrayWithHeight 状态将不起作用,因为它尚未更新。请改用当前高度参考值。

const [height, setHeight] = useState(0);
const [arrayWithHeight, setArrayWithHeight] = useState([]);

const ref = useRef(null);

useEffect(() => {
  setHeight(ref.current.clientHeight);
  addItemsToArray(ref.current.clientHeight);
}, [addItemsToArray]);



function addItemsToArray(height) {
  setArrayWithHeight(heights => [...heights, height]);
}

更新

您只有一个 ref,每个段落都需要一个 ref 才能获得每个段落的高度。以下是一种存储 refs 数组的方法 and 获取它们的计算高度。将高度数组散布到Math.Max函数中到return最大高度值

const [height, setHeight] = useState(0);

const heightRefs = useRef([]);

heightRefs.current = data.map((_, i) => heightRefs.current[i] ?? createRef());

useLayoutEffect(() => {
  setHeight(
    Math.max(
      ...heightRefs.current.map((el) =>
        Number(getComputedStyle(el.current).height.match(/\d+/).pop())
      )
    )
  );
}, []);

...

<div>
  {data.map((el, i) => (
    <p
      key={el}
      ref={heightRefs.current[i]}   // <-- ref by index
      style={{ minHeight: height }} // <-- set a minimum height
    >
      {el}
    </p>
  ))}
</div>