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

React表单提交时如何获取动态/多字段的输入值?

解决方案

提供两种无第三方依赖的实现方案,可根据你的改造需求选择:


方案1:状态提升(推荐,长期维护更友好)

将动态字段的状态从子组件移到表单所在的父组件维护,提交时直接读取状态即可,符合React单向数据流的标准设计。

改造步骤

  1. 调整动态字段组件为受控组件,从props接收状态和操作方法:
const ItemNameTextFields = ({itemNames, onInputChange, onAddField}) => {
    return (
        itemNames.map((itemName, i) => (
            <Box component='span' key={`item_${i}`} sx={{display: 'flex', flexWrap: 'wrap'}}>
                <TextField
                    value={itemName}
                    onChange={e => onInputChange(i, e)}
                    label={`Item ${i+1}`}
                    name={`item_${i}`}
                    className={classes.itemName}
                />
                {itemNames.length-1 === i &&
                    <Button
                        endIcon={<Icon icon={plusCircleOutline} />}
                        onClick={onAddField}
                    >
                        <small>Add another</small>
                    </Button>
                }
            </Box>
        ))
    );
}
  1. 父组件维护状态,提交时直接取值:
// 父组件内声明动态字段的状态
const [itemNames, setItemNames] = React.useState(['']);

const addItemNameField = () => setItemNames([...itemNames, '']);
const handleInputChange = (i, e) => {
    const values = [...itemNames];
    values[i] = e.target.value;
    setItemNames(values);
}

const handleSubmit = e => {
    e.preventDefault();
    let obj = {
        name: e.target['name'].value || '',
        // 直接取状态作为items数组,可加filter(Boolean)过滤空项
        items: itemNames.filter(Boolean)
    };
    // 若需要单独item_x的字段格式,添加以下逻辑即可
    // itemNames.forEach((val, idx) => obj[`item_${idx+1}`] = val);
    console.log(obj);
}

// 渲染时传递props
<form onSubmit={handleSubmit}>
    {/* 其他表单项 */}
    <ItemNameTextFields 
        itemNames={itemNames}
        onInputChange={handleInputChange}
        onAddField={addItemNameField}
    />
    <button type="submit">提交</button>
</form>

方案2:FormData直接读取(改造成本极低)

如果不想调整现有组件的状态结构,可以直接通过FormData读取表单内所有带item_前缀的字段值,不需要修改子组件代码。

改造步骤

直接修改提交逻辑即可:

const handleSubmit = e => {
    e.preventDefault();
    const formData = new FormData(e.target);
    let obj = {
        name: e.target['name'].value || '',
        items: []
    };

    // 遍历所有表单项匹配动态字段
    for (const [fieldName, fieldValue] of formData.entries()) {
        if (fieldName.startsWith('item_')) {
            // 要数组格式直接push
            obj.items.push(fieldValue);
            // 要单独item_x格式直接赋值:
            // obj[fieldName] = fieldValue;
        }
    }
    console.log(obj);
}

注:Material UI的TextField会自动把name属性透传给原生input,FormData可以正常识别读取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:36:02