React动态增删行 删除指定行时下方所有行被连带删除问题
React动态增删表单行异常修复
我开发了一款支持动态添加、删除组件行的React程序,具体实现与问题如下:
行组件(Dselect)
行组件样式如下:
行组件实现代码:
import Select from "react-select"; import { Row, Col, Button, Container, Form } from "react-bootstrap"; import React, { useState, useEffect } from "react"; const baseurl = "http://192.168.121.10:5000/api"; const Dselect = (props) => { const [pdtCodeOptions, setPdtCodeOptions] = useState([]); const [catListOptions, setCatListOptions] = useState([]); const [pdtListOptions, setPdtListOptions] = useState([]); const [selectedCat, setSelectedCategory] = useState(); const [selectedPcode, setSelectedPCode] = useState(); const [selectedPName, setSelectedPName] = useState(); useEffect(() => { const fetchCat = async () => { const res = await fetch(`${baseurl}/cat`); const cList = await res.json(); let catOpt = []; for (let i = 0; i < cList.length; i++) { catOpt.push({ label: cList[i].category, value: cList[i].category }); } setCatListOptions(catOpt); }; const fetchPdtCode = async () => { const res = await fetch(`${baseurl}/pdtlist`); const pList = await res.json(); const pdtList = []; for (let i = 0; i < pList.length; i++) { pdtList.push({ label: pList[i].pdt_id, value: pList[i].pdt_id }); } setPdtCodeOptions(pdtList); }; fetchCat(); fetchPdtCode(); }, []); const getPdtDetails = async (e) => { const pdtID = e.value; const res = await fetch(`${baseurl}/details`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ data: pdtID }), }); const detList = await res.json(); const pdt_name = detList[0].pdt_name; const category = detList[0].category; setSelectedCategory({ label: category, value: category }); setSelectedPName({ label: pdt_name, value: pdt_name }); }; const updateList = async (e) => { const catVal = e.value; const res = await fetch(`${baseurl}/pdtList`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ data: catVal }), }); const pdtList = await res.json(); const catPdtList = []; for (let i = 0; i < pdtList.length; i++) { catPdtList.push({ label: pdtList[i].pdt_name, value: pdtList[i].pdt_name, }); } setPdtListOptions(catPdtList); }; const getPdtcode = async (e) => { const pdtVal = e.value; const res = await fetch(`${baseurl}/pdtCode`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ data: pdtVal }), }); const code = await res.json(); setSelectedPCode(code); }; return ( <Row className="mt-3"> <Col lg={3} md={3} xs={3}> <Select options={pdtCodeOptions} placeholder="Select product" value={selectedPcode} onChange={(e) => { setSelectedPCode(e); getPdtDetails(e); }} /> </Col> <Col lg={3} md={3} xs={3}> <Select options={catListOptions} placeholder="Category" value={selectedCat} onChange={(e) => { setSelectedCategory(e); updateList(e); }} /> </Col> <Col lg={3} md={3} xs={3}> <Select options={pdtListOptions} onChange={(e) => { setSelectedPName(e); getPdtcode(e); }} value={selectedPName} placeholder="Select product" /> </Col> <Col lg={2} md={2} xs={2}> <Button type="button" onClick={() => props.onDelete(props.r)} className="btn btn-secondary" > Del </Button> </Col> </Row> ); }; export default Dselect;
父组件增删逻辑
点击Add按钮即可新增组件行,修复后的父组件代码如下:
import React from "react"; import Dselect from "../components/dSelect"; import { Form, Button } from "react-bootstrap"; import { useState } from "react"; const TableShow = () => { // 替换原直接存储JSX的逻辑,改为存储行唯一标识 const [rowIds, setRowIds] = useState([0]); const addRow = () => { const newId = rowIds.length > 0 ? Math.max(...rowIds) + 1 : 0; setRowIds([...rowIds, newId]); }; const delRow = (targetIndex) => { // 替换原splice删2个元素的错误逻辑,用不可变数据方式过滤 setRowIds(rowIds.filter((_, index) => index !== targetIndex)); }; return ( <div> <Button onClick={addRow}>Add</Button> <Form> {rowIds.map((id, index) => ( <Dselect key={id} r={index} onDelete={delRow} /> ))} </Form> </div> ); }; export default TableShow;
核心错误点
- 初始渲染的第一行组件没有传入
onDelete回调,点击删除按钮时触发参数异常 - 原
delRow方法中splice第二个参数错误传入2,每次删除操作会移除从索引位置开始的2个元素 - 原逻辑直接将JSX元素存在state中管理,自定义key和数组实际索引不匹配,React虚拟DOM diff时出现渲染错位,导致点击删除后下方行全部消失
- 子组件三个Select的
onChange回调中,更新状态时错误传入旧state值,选值功能本身存在失效bug
问题复现

➡
内容的提问来源于stack exchange,提问作者Maya
相关产品推荐
相关产品推荐

