根据组件调用的数量从现有数组构建新数组

Posted

技术标签:

【中文标题】根据组件调用的数量从现有数组构建新数组【英文标题】:Build new array from existing array based on number of component calls 【发布时间】:2019-11-21 02:00:37 【问题描述】:

背景故事

注意:此问题是对T.J. Crowder 提供的here 答案的扩展。

我对此进行了扩展,创建了一个状态来保存行数组,以便我可以使用 setState 更新数组(从中删除)。

我添加了一个handleClick 函数来处理我希望用户能够根据被单击元素的索引对数组执行的操作。 (目前只包括右键单击从数组中删除目标索引。

/rowList.js

import React,  Component  from "react";
import Row0 from "./../rows/row0";
import Row1 from "./../rows/row1";
import Row2 from "./../rows/row2";
import Row3 from "./../rows/row3";

const row0 = () => <Row0 />;
const row1 = () => <Row1 />;
const row2 = () => <Row2 />;
const row3 = () => <Row3 />;
class RowInfo 
  static id = 0;
  constructor(Comp) 
    this.Comp = Comp;
    this.id = RowInfo.id++;
  

class RowList extends Component 
  constructor() 
    super();
    this.state = 
      rows: [
        new RowInfo(row0),
        new RowInfo(row1),
        new RowInfo(row2),
        new RowInfo(row3)
      ]
    ;
  
  handleClick = (a, b) => e => 
    e.preventDefault();
    if (e.nativeEvent.which === 1) 
      //left click
      console.log(a); //for testing
      console.log(b); //for testing
     else if (e.nativeEvent.which === 3) 
      //right click
      this.setState(
        rows: this.state.rows.filter((_, i) => i !== a)
      );
    
  ;

  render() 
    return (
      <>
        this.state.rows.map(( id, Comp ) => (
          <tr
            key=id
            onClick=this.handleClick(id)
            onContextMenu=this.handleClick(id)
          >
            <Comp />
          </tr>
        ))
      </>
    );
  

export default RowList;

然后我测试了两次调用&lt;RowList /&gt; 组件,以便我可以测试跨两个组件删除行。

注意:Mod0 被导入到 /main.js 文件中,该文件被导入到 /index.js 中,在 index.html 中被渲染到 &lt;div id="root"&gt;&lt;/div&gt;

/mod0.js

import React,  Component  from "react";
import RowList from "./../rows/rowList";
class Mod0 extends Component 
  render() 
    return (
      <>
        <table>
          <tbody>
            <RowList />
          </tbody>
        </table>
        <table>
          <tbody>
            <RowList />
          </tbody>
        </table>
      </>
    );
  

问题

在测试删除时,我意识到一个关键错误,我目前的知识只能让我相对确定其性质,因此我的解释可能不准确/有缺陷。看来我只能从&lt;RowList /&gt; 中呈现的前 4 行中删除,因为后 4 行不对应于this.state.rows 中的数组。

我认为解决方案是基于原始状态数组和调用&lt;RowList /&gt; 的次数构建一个新数组。而是渲染该数组。

也许我可以更新状态,开始时可能看起来像这样:

constructor() 
    super();
    this.state = 
      rows: [
        new RowInfo(row0),
        new RowInfo(row1),
        new RowInfo(row2),
        new RowInfo(row3)
      ],
      rendRows: this.rendRowsTemp
    ;
    this.rendRowsTemp = []; //push to build a new array into here?
  

然后像这样使用新数组:

  render() 
    return (
      <>
        this.state.newRows.map(( id, Comp ) => (
          <tr
            key=id
            onClick=this.handleClick(id)
            onContextMenu=this.handleClick(id)
          >
            <Comp />
          </tr>
        ))
      </>
    );
  

预期结果

我需要一个方法来基于原始状态数组和调用&lt;RowList /&gt; 的次数来构建新数组。

【问题讨论】:

我认为问题是在过滤器的条件下 (this.state.rows.filter((_, i) =&gt; i !== a)) 你在数组中使用RowInfo 的索引而不是它的 ID,试试:this.state.rows.filter(( id ) =&gt; id !== a) 你能解释一下当你点击 2nd RowList 中的某一行时会发生什么吗? @Titus 谢谢!一切都解决了,你应该把它作为答案发布,这样我就可以打勾了 【参考方案1】:

我认为问题在于,在过滤条件 (this.state.rows.filter((_, i) =&gt; i !== a)) 中,您使用的是数组中的 RowInfo 索引而不是它的 ID,请尝试:this.state.rows.filter(( id ) =&gt; id !== a)

【讨论】:

以上是关于根据组件调用的数量从现有数组构建新数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在javascript中从现有数组创建一个新数组

如何根据字符串数量的输入在 C++ 中创建数组?

在 c# 中构建一个整数数组,每个调用 c++ 或在 c++ 中构建并传递给 c#?

useState setter 方法不更新数组

当参数之一是指针数组时,如何从 C# 调用 C++ DLL

用php根据数组更新html页面