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

React组件接收对象类型props变更时未更新,如何循环对象属性生成表单?

问题原因分析

你的代码无法正常更新的核心原因有两点:

  1. 使用了defaultValue为input赋值:该属性是非受控组件专属属性,仅在组件首次挂载时生效,后续data状态更新时不会同步修改input的显示值。你修改为value后可以正常更新,是因为value是受控属性,会跟随绑定的状态实时同步。
  2. 依赖对比的潜在问题:useEffect的依赖项是对象类型的row,React依赖对比默认是浅比较,如果父组件更新row时是直接修改原对象属性(而非生成新的对象实例),浅比较会判定row没有变化,useEffect不会触发更新。建议父组件更新row时使用新对象:setRow(prev => ({...prev, 要修改的属性: '新值'}))。
循环遍历生成表单的解决方案

方案1:受控表单实现(推荐)

受控表单方便后续做校验、数据收集,是React官方推荐的表单处理方式:

import React, {useState, useEffect} from "react";

const Form = ({row}) => {
  const [data, setData] = useState(row);

  useEffect(() => {
    setData(row);
  }, [row]);

  // 同步用户输入到状态
  const handleChange = (e) => {
    const {name, value} = e.target;
    setData(prev => ({...prev, [name]: value}));
  };

  return (
    <>
      {Object.keys(data).map((head) => {
        // 遍历生成元素必须加唯一key,避免diff异常
        return (
          <input
            key={head}
            type="text"
            name={head}
            value={data[head] ?? ""}
            onChange={handleChange}
          />
        );
      })}
    </>
  );
};

export default Form;

方案2:非受控表单实现

如果你不需要实时同步输入到状态,坚持用defaultValue,可以通过修改key属性触发input重绘:

import React, {useState, useEffect} from "react";

const Form = ({row}) => {
  const [data, setData] = useState(row);

  useEffect(() => {
    setData(row);
  }, [row]);

  return (
    <>
      {Object.keys(data).map((head) => {
        // key中加入row的唯一标识,row变化时key变化,React会销毁旧input重新创建,defaultValue会重新赋值
        return (
          <input
            key={`${row.ID}-${head}`}
            type="text"
            name={head}
            defaultValue={data[head] ?? ""}
          />
        );
      })}
    </>
  );
};

如果row没有唯一ID,可以用key={${JSON.stringify(row)}-${head}}替代,仅适合row结构不复杂的场景。

补充注意事项
  • 普通业务对象遍历属性用Object.keys即可,只有需要遍历不可枚举属性时才需要用Object.getOwnPropertyNames
  • 所有遍历生成的React列表元素必须加唯一key属性,避免渲染异常和性能问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:54:00