如何从 DOM 中删除数组的选定索引并反映 React 状态的变化?
Posted
技术标签:
【中文标题】如何从 DOM 中删除数组的选定索引并反映 React 状态的变化?【英文标题】:How to remove selected index of an array from the DOM and reflect the change in React state? 【发布时间】:2021-09-03 09:20:55 【问题描述】:在我的 react 应用程序中,我有一组对象数据,这些数据可以渲染到表中。我拥有的数据的数据结构如下:
this.state =
inspectionViewAllRsData: [
INSPN_PERFORMER_CD: label: "Contractor", value: "C"
,
INSPN_RSN_CD: label: "Initial", value: "INIT"
,
INSPN_STS_CD: label: "", value: "1000"
]
这是我的表格代码:
<table>
<tr>
<th>Performed By</th>
<th>Inspection</th>
<th>Residence Size</th>
</tr>
this.state.inspectionViewAllRsData.map((item, i) => (
<tr>
<td>item.INSPN_PERFORMER_CD.label <button id="close-btn" onClick=() => this.handleRemove(i)>X</button></td>
<td>item.INSPN_RSN_CD.label</td>
<td>item.RSDNC_SIZE_QTY.value</td>
</tr>
))
</table>
当我单击“X”按钮时,我想要做的是从状态中删除数组的选定索引。这是我试图做的,但它给了我一个错误row.filter is not a function
handleRemove = index =>
const newData = this.state.inspectionViewAllRsData.map(row =>
return row.filter((el, i) => i !== index);
);
console.log(newData)
this.setState( inspectionViewAllRsData: newData );
有人可以帮我解决我的功能吗?任何帮助将不胜感激。
【问题讨论】:
什么是inspectionViewAllRsData
?它是您第一个代码块中的数据键吗?
这是我忘记在上面的帖子中更改的状态数组的名称。感谢您注意到这一点。
看this.state.inspectionViewAllRsData.map
我不相信inspectionViewAllRsData
中的数据结构是正确的;该地图中的每个项目都类似于 INSPN_PERFORMER_CD: label: "Contractor", value: "C"
,而地图中的组件输出预计也能够访问INSPN_RSN_CD
和RSDNC_SIZE_QTY
。
【参考方案1】:
你们很亲密。您只是试图做太多事情,在数组的每个单独元素上使用 map
到 filter
- 这是不可能的,因为这些是对象,而不是数组。您只需要一个***过滤器。用这个替换newData
的定义,一切都应该没问题:
const newData = this.state.inspectionViewAllRsData.filter((el, i) => i !== index);
【讨论】:
谢谢罗宾。我不再看到错误消息,但状态数据仍未被删除。知道可能是什么问题吗? 在将我的 handleRemove 处理程序移动到父组件后,我终于得到了这个工作,它开始工作得很好。感谢您的帮助。【参考方案2】:我不知道你是如何设法呈现这个的,因为在我看来你混淆了数据结构和实现。
特别是:
this.state.inspectionViewAllRsData.map((item, i) => (
<tr>
<td>item.INSPN_PERFORMER_CD.label <button id="close-btn" onClick=() => this.handleRemove(i)>X</button></td>
<td>item.INSPN_RSN_CD.label</td>
<td>item.RSDNC_SIZE_QTY.value</td>
</tr>
))
每个item
都类似于:
property: label: "string", value: "string"
所以你基本上有一个由Object
类型的3 个元素组成的数组,当map
函数只选择其中一个元素时,你试图渲染它们。
我猜你的意思是有一个对象数组 (Object[]
),其中每个 Object
有 3 个属性,所以你的“硬编码”数据应该是这样的:
inspectionViewAllRsData = [
INSPN_PERFORMER_CD: label: "Contractor", value: "C",
INSPN_RSN_CD: label: "Initial", value: "INIT",
INSPN_STS_CD: label: "", value: "1000"
,
// Other Objects with this structure
]
我希望我写的内容足够清楚,并且我猜对了你的意图,如果没有,请告诉我,我会编辑我的答案。
编辑
我认为您应该以更易于阅读/使用数据结构的方式解析您的输入。 这是我的尝试,我将尝试解释我的思考过程。
在您的状态下,您应该添加另一个空数组:
this.state=
inspectionBlaBlah: //your initial data structure,
newDataArray: []
在您的构造函数中,您应该添加一个Object
,这将有助于重新组织您的数据:
let toFillWithProperties = ;
之后你应该这样做:
inspectionViewAllRsData.map(
// Cycle through your initial array
(item, i) =>
// Cycle through the properties of every item of your array
return Object.keys(item).map(
(property, j) =>
// Create the same key/value for each property in your new object
toFillWithProperties[property] = item[property];
if ((i + 1) % 3 == 0)
// Every 3 steps you update your new Array
this.state.newDataArray.push(toFillWithProperties);
toFillWithProperties = ;
))
完成后,您可以像以前一样渲染表格,但您应该使用this.state.newDataArray
上的map
函数。这同样适用于您的处理函数,在您的 newDataArray
上使用 setState
。
它应该以这种方式工作,但我真的不鼓励你使用这种数据,因为这个过程假设你的数组中的每 3 个元素都会在结构中重复,它不会在任何其他元素中工作案例。
【讨论】:
Lucayam,你理解正确。这就是后端将数据返回到前端的方式(我知道这不是一个好的格式),但这就是 api 的结构来自后端的样子。有什么方法可以在单击按钮时从 UI 中删除选定的表格列? 我认为唯一的“简单”方法是从 API 中检索到您的对象,保存一个空对象以供以后使用,然后在检索到的对象上进行双循环。在你内在循环的每一步中,你都应该用你拥有的属性填充你的空对象。每 3 步(0,1,2...等等),您应该将此对象推送到另一个数组中,重新清空您创建的对象,然后继续循环。我将尝试编辑我的答案并发布一些关于此的代码。如果你不这样做,我认为这样渲染结构并不容易。 P.S:更改后端服务:D 感谢Lucayam的所有帮助。在将我的 handleRemove 处理程序移动到父组件后,我终于得到了这个工作。感谢您的帮助和时间。以上是关于如何从 DOM 中删除数组的选定索引并反映 React 状态的变化?的主要内容,如果未能解决你的问题,请参考以下文章