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

在React类组件中实现动态添加输入字段

React类组件实现动态添加输入字段并获取数据

问题说明

需要在React类组件中实现点击“添加”按钮时动态复制输入字段,同时能获取所有字段的输入数据。现有参考教程均基于函数组件的useState实现,需适配类组件写法。

解决方案

类组件通过this.state管理动态字段数组替代函数组件的useState,核心实现步骤:

  • 在类构造函数中初始化状态,存储动态字段的数据集合
  • 实现添加字段方法,向状态数组中追加新的空字段
  • 实现字段值变更方法,更新对应索引的字段数据
  • 遍历状态数组渲染所有输入字段,绑定对应的变更事件

完整代码示例

import React from 'react';
import { Paper, Grid, TextField, Typography, Button } from '@mui/material';

// 提取公共输入字段组件到类外部
export const getTextFieldForSmall = (
  label,
  placeholder,
  value,
  onChange,
  error = false,
  helperText = '',
) => (
  <TextField
    fullWidth
    label={label}
    placeholder={placeholder}
    value={value}
    onChange={onChange}
    error={error}
    helperText={helperText}
    margin='none'
    size='small'
  />
);

class SerialQRScanClass extends React.PureComponent {
  constructor(props) {
    super(props);
    // 初始化状态:存储所有动态字段数据,默认包含一个空字段
    this.state = {
      serialFields: [{ serialStart: '' }]
    };
  }

  // 添加新字段
  handleAddField = () => {
    this.setState(prevState => ({
      serialFields: [...prevState.serialFields, { serialStart: '' }]
    }));
  };

  // 更新指定索引的字段值
  handleFieldChange = (index, value) => {
    this.setState(prevState => {
      const updatedFields = [...prevState.serialFields];
      updatedFields[index].serialStart = value;
      return { serialFields: updatedFields };
    });
    // 可在此处直接获取所有字段数据,或在需要时从state读取
    console.log('所有字段数据:', this.state.serialFields);
  };

  // 可选:删除指定索引的字段(保留至少一个字段)
  handleRemoveField = (index) => {
    if (this.state.serialFields.length <= 1) return;
    this.setState(prevState => ({
      serialFields: prevState.serialFields.filter((_, i) => i !== index)
    }));
  };

  xyz(): JSX.Element {
    const { serialFields } = this.state;

    return (
      <Paper elevation={3} className='abc'>
        {/* 添加按钮 */}
        <Button 
          variant="contained" 
          onClick={this.handleAddField}
          style={{ marginBottom: 16 }}
        >
          ADD NEW FIELD
        </Button>

        {/* 遍历渲染所有动态字段 */}
        {serialFields.map((field, index) => (
          <div key={index} style={{ marginBottom: 16 }}>
            <Grid container alignItems='flex-end' spacing={2}>
              <Grid item className='bcd' xs={10}>
                {getTextFieldForSmall(
                  <Typography variant='caption'>Title</Typography>,
                  'Serial start',
                  field.serialStart,
                  (e) => this.handleFieldChange(index, e.target.value),
                  false,
                  'Wrong serial'
                )}
              </Grid>
              {/* 删除按钮 */}
              {serialFields.length > 1 && (
                <Grid item xs={2}>
                  <Button 
                    variant="outlined" 
                    color="error"
                    onClick={() => this.handleRemoveField(index)}
                  >
                    删除
                  </Button>
                </Grid>
              )}
            </Grid>
          </div>
        ))}
      </Paper>
    );
  }

  render() {
    return this.xyz();
  }
}

export default SerialQRScanClass;

关键说明

  1. 状态管理:用this.state.serialFields数组存储每个字段的数据,每个元素为包含字段值的对象,方便后续扩展更多字段(如Serial end)。
  2. 字段更新:handleFieldChange通过索引定位目标字段,确保每个输入框的变更能正确映射到状态数组的对应位置。
  3. 不可变更新:更新状态时始终创建新数组/对象,避免直接修改原状态,符合React状态更新规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:55:25