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

React动态调整font-size适配固定容器时字号不更新问题求助

问题核心原因
  • React类组件只有调用setState()或者forceUpdate()才会触发重渲染,直接修改实例属性this.size不会触发render方法重新执行,模板中绑定的fontSize永远是初始化的50px,这是字号不更新的根本原因。
  • componentDidMount中递归调用自身的逻辑存在严重缺陷:第一次执行就会把字号从50px直接减到10px,若仍超出容器高度会触发无限递归直到栈溢出,没有合理的调整步长和终止条件。
  • 原代码未初始化state,也未定义handleChange、handleSubmit方法,运行时会直接报错。
  • 直接通过ref修改DOM样式不生效,是因为后续React如果触发重渲染,会用模板中绑定的初始this.size值覆盖手动修改的样式。
修复方案
  1. 将size放到组件state中管理,修改时调用setState触发重渲染。
  2. 重写字号适配逻辑:设置合理的调整步长(比如每次减1px),循环判断直到文本尺寸小于容器尺寸,再更新state,同时设置最小字号阈值避免死循环。
  3. 补全缺失的state初始化和事件方法。
修复后代码
import React from "react";
class NewDrive extends React.Component {
  constructor(props) {
    super(props);
    // 初始化state
    this.state = {
      from: "",
      size: "50px"
    };

    this.myOutputRef = React.createRef();
    this.myOutputContainerRef = React.createRef();
    
    // 绑定事件this指向
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    const output = this.myOutputRef.current;
    const outputContainer = this.myOutputContainerRef.current;
    let currentSize = 50;
    // 每次减1px,直到文本高度小于容器高度,最小字号设为12px避免无限循环
    while (output.clientHeight >= outputContainer.clientHeight && currentSize > 12) {
      currentSize -= 1;
      output.style.fontSize = `${currentSize}px`;
    }
    // 最终更新到state,同步到模板
    this.setState({ size: `${currentSize}px` });
  }

  handleChange(e) {
    this.setState({ from: e.target.value });
  }

  handleSubmit(e) {
    e.preventDefault();
    // 自定义提交逻辑
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <div className="input-wrapper">
          {/* 需给label容器设置固定的宽高样式,否则无法正确判断溢出条件 */}
          <label ref={this.myOutputContainerRef} style={{ display: 'block', width: '100px', height: '30px', overflow: 'hidden' }}>
            {/* 文本节点设置为inline-block才能正确拿到实际clientHeight */}
            <div style={{ fontSize: this.state.size, display: 'inline-block' }} ref={this.myOutputRef}>
              Gas cost
            </div>
          </label>
          <input
            type="text"
            value={this.state.from}
            onChange={this.handleChange}
          />
        </div>
      </form>
    );
  }
}

export default NewDrive;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:45:05