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
相关产品推荐
相关产品推荐

