如何从 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_CDRSDNC_SIZE_QTY 【参考方案1】:

你们很亲密。您只是试图做太多事情,在数组的每个单独元素上使用 mapfilter - 这是不可能的,因为这些是对象,而不是数组。您只需要一个***过滤器。用这个替换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 状态的变化?的主要内容,如果未能解决你的问题,请参考以下文章

如何从特定单击的响应中删除数组中的索引

表从数组中删除索引路径行值

firebase 按索引从字段数组中删除对象

从Swift数组中的选定复选标记中删除字符串

如何从select2多选中的选项列表中删除选定的选项并按选择的顺序显示选定的选项

如何将 UITableViewCell 内的 UICollectionViewCell 的选定索引路径保存到数组中?