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

React数组映射时状态传递给所有Input组件的问题排查

问题:遍历生成的Input组件共用状态,无法独立输入

我用父表单组件遍历对象数组渲染多个子<Input>组件,但所有输入字段共用同一个状态,输入时所有框同步显示内容。希望每个输入框的值独立存储,比如"全名"和"邮箱"各有自己的状态值,请问哪里错了?


父组件代码

import React, { useState } from 'react';
import { formFieldsData } from './FormFields';
import Input from './Input';

export default function Form() {
    const [inputValue, setInputValue] = useState('');

    const handleChange = (e) => {
        setInputValue(e.target.value)
    }

    return (
        <form>
            {formFieldsData.map((item) => (
                <Input
                    key={item.id}
                    id={item.id}
                    label={item.label}
                    type={item.type}
                    placeholder={item.placeholder}
                    inputValue={inputValue}
                    onChange={(e) => handleChange(e)}
                />
            ))}
        </form>
    )
}

子组件代码

import React from 'react';
import styles from './forms.module.scss';
import RangeInput from './RangeInput';

export default function Input({ inputValue, onChange, type, id, placeholder = '', label }) {
    return (
        <div className={styles.form__row}>
            <label htmlFor={id}>{label}: {inputValue}</label>
            <input
                required
                type={type}
                id={id}
                name={id}
                placeholder={placeholder}
                className={styles.input}
                value={inputValue}
                onChange={onChange}
            />
        </div>
    )
}

formFieldsData.js代码

export const formFieldsData = [
  {
    label: '全名',
    type: 'text',
    id: 'fullName',
    placeholder: '请输入全名'
  },
  {
    label: '邮箱',
    type: 'email',
    id: 'emailAddress',
    placeholder: '请输入邮箱地址'
  },
  {
    label: '出生日期',
    type: 'date',
    id: 'dateOfBirth',
  },
  {
    label: '最喜欢的颜色',
    type: 'color',
    id: 'favouriteColour',
  },
  {
    label: '薪资',
    type: 'range',
    id: 'salary',
  },  
];

错误原因

你用了单一字符串状态inputValue,所有Input组件都绑定这个值。不管哪个输入框触发onChange,都会把这个字符串替换成当前输入值,导致所有输入框同步显示相同内容。

修改方案

把状态改成对象类型,每个字段的id作为属性名存储对应输入值,这样每个输入框可以独立更新自己的状态属性。

修改后的父组件代码

import React, { useState } from 'react';
import { formFieldsData } from './FormFields';
import Input from './Input';

export default function Form() {
    // 初始化状态为对象,每个字段id对应空值
    const [formValues, setFormValues] = useState(() => {
        return formFieldsData.reduce((acc, item) => {
            acc[item.id] = '';
            return acc;
        }, {});
    });

    const handleChange = (e) => {
        const { id, value } = e.target;
        // 只更新当前输入框对应的属性
        setFormValues(prev => ({
            ...prev,
            [id]: value
        }));
    }

    return (
        <form>
            {formFieldsData.map((item) => (
                <Input
                    key={item.id}
                    id={item.id}
                    label={item.label}
                    type={item.type}
                    placeholder={item.placeholder}
                    // 传递当前字段对应的状态值
                    inputValue={formValues[item.id]}
                    onChange={handleChange}
                />
            ))}
        </form>
    )
}

说明

  1. 初始化状态时,用reduce遍历formFieldsData,生成以每个字段id为键的对象,初始值为空字符串。
  2. handleChange里通过e.target.id拿到当前输入框的标识,只更新对象中对应键的值,其他属性保持不变(用扩展运算符...prev复制之前的状态)。
  3. 渲染Input时,传递formValues[item.id]作为当前字段的值,每个输入框绑定自己的状态属性。

修改后,每个输入框的值就会独立存储和更新,不会互相影响了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:54:55