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

React动态添加输入框后所有项值同步问题如何解决

解决动态添加表单字段值同步问题

问题根源

你遇到的所有变体字段值同步变化的问题,核心原因是每次添加新字段时,你直接复用了同一个AddProductVariationInitialValue对象的引用。当多个变体项共享同一个对象实例时,修改其中任意一个的属性,所有关联的项都会同步更新。

解决方案

要让每个变体字段拥有独立的值,需要保证每次添加的新字段都是一个全新的对象实例,而不是复用同一个引用。同时优化状态更新逻辑,确保修改单个字段时不会影响其他项。

步骤1:创建初始值的深拷贝

修改addVariationFields函数,每次添加新字段时,对初始值对象进行深拷贝:

const addVariationFields = () => {
    // 使用structuredClone深拷贝,支持复杂对象(嵌套结构)
    const newField = structuredClone(AddProductVariationInitialValue);
    // 如果是简单平面对象,也可以用扩展运算符:
    // const newField = {...AddProductVariationInitialValue};

    setInputVariationFields(prev => [...prev, newField]);
}

步骤2:优化状态更新逻辑

在BaseInput的onChange事件中,使用函数式更新获取最新状态,并复制当前对象后再修改属性,避免直接修改原状态对象:

<BaseInput
    key={`name_1_${index}`}
    id={`${index}`}
    name={`name_1_${index}`}
    type='text'
    value={element.name_1 || ''}
    onChange={(e) => {
        setInputVariationFields(prevFields => {
            // 复制数组和当前索引的对象
            const updatedFields = [...prevFields];
            updatedFields[index] = {
                ...updatedFields[index],
                name_1: e.target.value
            };
            return updatedFields;
        });
    }}
    placeholder='Product variation name 1'
/>

注意:你原来的代码里BaseInput重复写了两次value属性,需要删除其中一个。

修正后的完整核心代码

const [inputVariationFields, setInputVariationFields] = useState<AddProductVariationForm[]>([])

const addVariationFields = () => {
    const newField = structuredClone(AddProductVariationInitialValue);
    setInputVariationFields(prev => [...prev, newField]);
}

const removeVariationFields = (i: number) => {
    setInputVariationFields(prev => prev.filter((_, idx) => idx !== i));
}

// 渲染部分
return (
    <>
        {inputVariationFields.map((element, index) => (
            <div className="my-3 p-3 border border-gray-lighter rounded" key={index}>
                <div className='w-full'>
                    <label htmlFor={`name_1_${index}`} className='font'>
                        Variation Name 1
                        <BaseInput
                            key={`name_1_${index}`}
                            id={`${index}`}
                            name={`name_1_${index}`}
                            type='text'
                            value={element.name_1 || ''}
                            onChange={(e) => {
                                setInputVariationFields(prevFields => {
                                    const updatedFields = [...prevFields];
                                    updatedFields[index] = {
                                        ...updatedFields[index],
                                        name_1: e.target.value
                                    };
                                    return updatedFields;
                                });
                            }}
                            placeholder='Product variation name 1'
                        />
                    </label>
                </div>

                {/* 其他表单字段... */}

                {index !== 0 && (
                    <div className='mt-5 mb-2'>
                        <OutlinedButton onClick={() => removeVariationFields(index)}>
                            Remove
                        </OutlinedButton>
                    </div>
                )}
            </div>
        ))}
        <div className="my-3">
            <PrimaryButton
                type='button'
                onClick={addVariationFields}
            >
                Add variation
            </PrimaryButton>
        </div>
    </>
);

额外说明

  • 如果AddProductVariationInitialValue是包含嵌套对象的复杂结构,必须使用structuredClone或者第三方库(如Lodash的cloneDeep)进行深拷贝;如果是简单平面对象,用扩展运算符{...obj}即可。
  • 使用函数式更新(setState(prev => ...))可以避免因状态异步更新导致的旧值覆盖问题,让状态更新更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:45:31