You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态记录表格渲染总高度时遇无限渲染循环问题求助

问题解决:表格动态记录总高度的无限循环与高度为0问题

问题原因分析

  1. 无限渲染循环:reportHeight的useCallback依赖了totalHeight,每次totalHeight更新都会导致reportHeight重新生成。CustomTd组件的useEffect依赖reportHeight,触发后又会调用reportHeight更新totalHeight,形成循环。
  2. 空依赖数组高度为0:组件挂载时DOM元素尚未完成渲染,此时获取到的高度为0,空依赖数组会让useEffect只执行一次,后续元素高度变化无法触发回调。

修复方案

  1. 优化reportHeight的依赖:利用setTotalHeight的函数式更新,不需要依赖totalHeight,这样reportHeight只会在组件初始化时创建一次,避免频繁更新。
  2. 过滤无效高度值:在CustomTd的useEffect中,只在lineHeight大于0时调用reportHeight,避免初始0值被累加。

修改后的代码

const text = "这里是长文本内容"; // 替换为实际长文本

const CustomTd: FC<IColumn> = ({ reportHeight, line }) => {
  const [lineRef, { height: lineHeight }] = useElementSize(); // usehooks-ts

  useEffect(() => {
    // 仅上报有效高度
    if (lineHeight > 0) {
      reportHeight(lineHeight);
    }
  }, [reportHeight, lineHeight]);

  return <Td ref={lineRef}>{line}</Td>;
};

const CustomTable: FC = () => {
  const [totalHeight, setTotalHeight] = useState(0);
  const [currentHeight, setCurrentHeight] = useState(0);

  const reportHeight = useCallback(
    (height: number) => {
      // 函数式更新无需依赖totalHeight
      setTotalHeight((prevTotalHeight) => prevTotalHeight + height);
      setCurrentHeight(height);
    },
    [] // 清空依赖,避免不必要的重新创建
  );

  return (
    <Table>
      {text.split(" ").map((word, index) => (
        <Tr key={index}> {/* 添加key避免React渲染警告 */}
          <CustomTd line={word} reportHeight={reportHeight} />
          <Td>{currentHeight}</Td>
          <Td>{totalHeight}</Td>
        </Tr>
      ))}
    </Table>
  );
};

额外优化建议

  • 若需避免重复累加相同高度(比如元素重渲染但高度未变),可在CustomTd中记录上一次上报的高度,仅当高度变化时触发reportHeight。

内容的提问来源于stack exchange,提问作者Viktar Beliakou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 10:02:33