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

