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

如何解决动态生成表单组件重渲染时的焦点丢失问题

解决动态表单重渲染丢失焦点的问题

问题根源

你遇到的焦点丢失,核心是**InputSwitch内部给子组件设置的key不稳定**——你用了field对象作为key,每次字段值更新时,field对象的引用会发生变化(比如更新value时可能生成了新对象),React会把它识别成全新的组件,卸载旧组件再挂载新的,焦点自然就丢了。外层循环的key用字段名是对的,不用改。

修复方案

直接修改InputSwitch内部子组件的key,改用稳定不变的标识(比如传入的id),或者干脆去掉内部的key(因为InputSwitch本身已经在外层循环里设置了唯一key,内部子组件不需要额外加key)。

修改后的InputSwitch代码

const InputSwitch = ({ id, field }) => {
    if (field.type === "text") {
      return (
        <BasicTextArea
          key={id} // 改用稳定的字段id作为key
          editable={store.editMode}
          sectionTitle={field.name}
          sectionInputId={id}
          inputValue={field.value}
          sectionInputPlaceholder={field.placeholder}
          onChange={updateContentFieldValue}
        />
      );
    }
    if (field.type === "list") {
      return (
        <List
          key={id} // 同样使用稳定的id
          editable={store.editMode}
          sectionTitle={field.name}
          sectionInputId={id}
          sectionInputPlaceholder={field.placeholder}
          items={field.value}
          onChange={updateContentFieldValue}
        />
      );
    }
}

额外优化建议

如果你的updateContentFieldValue方法在更新状态时是直接修改原field对象属性,建议改成不可变更新的方式,用展开运算符创建新对象,避免不必要的引用变化:

const updateContentFieldValue = (id, newValue) => {
  store.setState({
    fields: {
      ...store.fields,
      contentFields: {
        ...store.fields.contentFields,
        [id]: {
          ...store.fields.contentFields[id],
          value: newValue
        }
      }
    }
  });
}

这种方式能保证除value外,field的其他属性和引用变化最小,进一步提升组件渲染的稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:23:12