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

Material-ui TextField重新渲染后失焦,如何解决该问题?

问题原因分析

TextField失焦的核心原因

遍历渲染数组元素时没有为每个TextField设置稳定唯一的key属性:React的列表重渲染逻辑依赖key判断组件是否可复用,缺少稳定key的情况下,状态更新后React会判定所有TextField都是新组件,直接销毁旧组件并重建新组件,原有输入框的焦点就会丢失。
同时你在onChange中直接修改原状态数组sections[ind] = el属于违反React不可变更新原则的操作,会进一步干扰diff判断,提高组件销毁重建的概率。

TextareaAutosize未出现失焦的原因

TextareaAutosize是Material-UI对原生<textarea>标签的轻量封装,组件结构非常简单,diff识别成本极低;而TextField是复合组件,内部封装了标签、输入框、辅助提示等多个子组件,结构更复杂,在缺少稳定key的场景下,React diff算法对复合组件的复用判断准确率远低于简单组件,因此不会轻易触发销毁重建,也就没有失焦问题。

修复方案

步骤1:为列表项添加稳定唯一的key

首先为每个section项新增唯一业务标识作为key的来源,不要使用数组下标作为key(数组增删时下标会变化,仍属于不稳定key):

// 修改状态初始化代码,新增id字段作为唯一标识
const [sections, setSections] = useState([
    {
      id: 1,
      Title: "Introduction",
      Text: ""
    },
    {
      id: 2,
      Title: "Relationship",
      Text: ""
    },
    {
      id: 3,
      Title: "Monitoring",
      Text: ""
    }
]);

遍历渲染时为列表根节点绑定key:

sections.map((el, ind) => (
  // 用稳定的id作为key
  <div key={el.id}>
    {/* 原有TextField、TextareaAutosize代码 */}
  </div>
))

步骤2:修改onChange为不可变更新写法

删除直接修改原状态数组的逻辑,采用React推荐的不可变更新方式更新状态:

TextField的onChange修改为:

onChange={(event) => {
  setSections(prevSections => prevSections.map((item, i) => 
    i === ind ? {...item, Title: event.target.value} : item
  ))
}}

TextareaAutosize的onChange修改为:

onChange={(event) => {
  setSections(prevSections => prevSections.map((item, i) => 
    i === ind ? {...item, Text: event.target.value} : item
  ))
}}

修改完成后TextField就不会再出现输入失焦的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:27:02