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

React中useEffect与componentDidUpdate对比使用及功能实现问题

解决方案

核心问题定位

你出现无限循环的直接原因是把状态lines放到了useEffect的依赖数组中:当你在useEffect内部调用setLines修改lines的值时,会触发依赖项变化,进而重新执行useEffect、再次调用setLines,形成无限死循环。
另外你当前的依赖设置也不符合业务逻辑:触发SVG文本重新计算换行的触发源从来不是lines本身,而是外部传入的用户输入文本、SVG容器宽度、字体大小这些会影响换行结果的输入属性。

具体修改步骤

  1. 新增useRef获取用于计算文本宽度的SVG text元素的DOM引用,用来计算文本实际渲染宽度
  2. 调整useEffect的依赖数组,替换为text(用户输入的文本)、width(SVG文本容器宽度)、fontSize(字体大小)这类触发重新计算的变量
  3. 将原类组件中componentDidMount和componentDidUpdate里的换行计算逻辑移到useEffect内部,计算完成后调用setLines更新结果即可

代码示例

import { useRef, useState, useEffect } from 'react';

const Text = ({ text, width, fontSize = 16 }) => {
  // 用于获取计算宽度的隐藏text节点的引用
  const measureTextRef = useRef(null);
  const [lines, setLines] = useState([]);

  useEffect(() => {
    const measureEl = measureTextRef.current;
    // 边界判断:DOM不存在或文本为空时直接返回
    if (!measureEl || !text) return;
    
    const words = text.split(' ');
    let currentLine = [];
    const calculatedLines = [];
    // 清空之前的测量内容
    measureEl.textContent = '';

    for (let i = 0; i < words.length; i++) {
      currentLine.push(words[i]);
      measureEl.textContent = currentLine.join(' ');
      // 当当前行宽度超过容器宽度时换行
      if (measureEl.getComputedTextLength() > width) {
        // 把最后一个超出的单词放回下一行
        currentLine.pop();
        calculatedLines.push(currentLine.join(' '));
        currentLine = [words[i]];
      }
    }
    // 把最后剩余的内容加入行数组
    calculatedLines.push(currentLine.join(' '));

    // 更新lines状态,不会触发死循环
    setLines(calculatedLines);
  // 依赖项为所有会影响换行结果的输入参数,不要加入lines
  }, [text, width, fontSize]);

  return (
    <g>
      {/* 隐藏的测量用text节点,样式和实际渲染保持一致 */}
      <text ref={measureTextRef} fontSize={fontSize} style={{ visibility: 'hidden' }} />
      {/* 实际渲染的换行文本 */}
      <text fontSize={fontSize}>
        {lines.map((line, idx) => (
          <tspan key={idx} x={0} dy={fontSize * 1.2}>{line}</tspan>
        ))}
      </text>
    </g>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:27:01