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

React实现员工多银行信息动态录入功能问题求助

实现React表单多银行信息动态添加功能(适配Rails嵌套属性)

问题背景

我正在开发一个后端基于Rails、前端基于React的员工管理应用,员工模型字段较多,用Bootstrap标签页分组优化体验。现在卡在银行信息标签页:员工可以有多条银行信息,需要点击按钮新增录入行,但现有代码只支持单条。

核心修改思路

要支持动态多行,需要把单条银行信息的状态改成数组,同时调整表单输入的处理逻辑,适配Rails的accepts_nested_attributes_for要求。

1. 重构表单状态,存储多条银行信息

把原formValues里的type、account_title等单字段替换成数组bankDetails,初始化至少一条空数据:

const [formValues, setFormValues] = useState({
  // 其他原有字段保持不变...
  bankDetails: [
    { type: null, account_title: null, account_number: null, bank_name: null }
  ]
});

2. 修改输入处理函数,支持数组字段

更新handleInputChange,通过字段名里的索引区分不同银行行:

const handleInputChange = (e, index) => {
  const { name, value } = e.target;
  const updatedBankDetails = [...formValues.bankDetails];
  updatedBankDetails[index] = { ...updatedBankDetails[index], [name]: value };
  setFormValues({ ...formValues, bankDetails: updatedBankDetails });
};

3. 添加新增银行行的方法

新增addBankDetail函数,点击按钮时往数组里添加一条空银行信息:

const addBankDetail = () => {
  setFormValues({
    ...formValues,
    bankDetails: [...formValues.bankDetails, { type: null, account_title: null, account_number: null, bank_name: null }]
  });
};

4. 更新提交数据结构

修改data1里的emp_bank_details_attributes,把bankDetails数组映射成Rails需要的格式:

emp_bank_details_attributes: formValues.bankDetails.map(detail => ({
  b_type: detail.type,
  account_title: detail.account_title,
  account_number: detail.account_number,
  bank_name: detail.bank_name
}))

5. 修改BankDetails组件,支持渲染多行

更新组件,接收单条银行数据、输入处理函数和索引,同时添加删除按钮(可选):

import React from 'react'
import bank_types from "Data/Bank";
import { FormGroup, Input, Row, Col, Label, Button } from "reactstrap";

const BankDetails = ({ bankDetail, handleInputChange, index, onDelete }) => {
  return (
    <Row className="mb-3">
      <Col md={2}>
        <FormGroup>
          <Label>TYPE</Label>
          <Input 
            name="type" 
            type="select" 
            value={bankDetail.type} 
            onChange={(e) => handleInputChange(e, index)}
          >
            <option value="">Please Select Bank Type</option>
            {bank_types.map((type) => (
              <option key={type.value} value={type.value}>{type.name}</option>
            ))}
          </Input>
        </FormGroup>
      </Col>

      <Col md={2}>
        <FormGroup>
          <Label>Account Title</Label>
          <Input 
            type="text" 
            name="account_title" 
            value={bankDetail.account_title} 
            onChange={(e) => handleInputChange(e, index)}
          />
        </FormGroup>
      </Col>

      <Col md={2}>
        <FormGroup>
          <Label>Account Number</Label>
          <Input 
            type="text" 
            name="account_number" 
            value={bankDetail.account_number} 
            onChange={(e) => handleInputChange(e, index)}
          />
        </FormGroup>
      </Col>

      <Col md={2}>
        <FormGroup>
          <Label>Bank Name</Label>
          <Input 
            type="text" 
            name="bank_name" 
            value={bankDetail.bank_name} 
            onChange={(e) => handleInputChange(e, index)}
          />
        </FormGroup>
      </Col>

      {index > 0 && (
        <Col md={2} className="d-flex align-items-end">
          <Button color="danger" onClick={() => onDelete(index)}>
            删除
          </Button>
        </Col>
      )}
    </Row>
  )
}

export default BankDetails

6. 在主组件中渲染所有银行行并添加新增按钮

修改NewEmployee组件的银行标签页部分,循环渲染BankDetails,并添加新增按钮:

<Tab eventKey="2" title="Bank Information">
  {formValues.bankDetails.map((detail, index) => (
    <BankDetails
      key={index}
      bankDetail={detail}
      handleInputChange={handleInputChange}
      index={index}
      onDelete={(idx) => {
        const updatedBankDetails = formValues.bankDetails.filter((_, i) => i !== idx);
        setFormValues({ ...formValues, bankDetails: updatedBankDetails });
      }}
    />
  ))}
  <Button onClick={addBankDetail} className="mt-2">
    新增银行信息
  </Button>
  <Button onClick={handlePreviousClick} className="mr-2 mt-2">
    Previous
  </Button>
  <Button onClick={handleNextClick} className="mt-2">Next</Button>
</Tab>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:07:46