猿问

我对Todo App删除功能的处理方式有误吗?

我正在学习 React,并且刚刚使用 React 创建了一个简单的待办事项应用程序。我的待办事项应用程序具有标准结构,即文本输入和旁边的“添加”按钮。用户将在输入中键入他们的待办事项,每次单击旁边的“添加”按钮时,他们输入的新有序列表将出现在输入和“添加”按钮下方。

用户还可以通过单独单击条目来删除待办事项条目,如下所示:


http://img.mukewang.com/63f8754400017c1406540270.jpg

为了完成这种删除条目的行为,我使用了这个删除函数:


delete(elem) {

    for (var i = 0; i < this.state.listArray.length; i++) {

      if (this.state.listArray[i] === elem) {

        this.state.listArray.splice(i, 1);

        this.setState({

          listArray: this.state.listArray

        });

        break;

      }

    }

  }

我的待办事项应用程序完全按照我希望的方式工作,但当我看到其他人对此删除功能的更传统方法时,他们要么只是简单地使用拼接方法或过滤方法。


对于拼接方法方法,当用户单击特定条目时,它们显然只是简单地从listArray中“删除”不需要的条目。这对我不起作用,因为使用此方法会导致我的所有条目都被删除,但我单击的条目除外,这是我要删除的条目。


另一方面,filter 方法方法显然是通过比较从子组件传递的数据elem与listArray中的每个元素来工作的,如果 for 循环中的元素不等于 elem ,那么它将被传递到一个新数组。这个新数组将不会被删除。这种方法比简单的拼接方法效果更好,但是,我在使用这种方法时遇到的一个问题是,如果我有多个具有相同值的条目,例如“喂狗”。我只想删除其中一个“喂狗”条目,但它会同时删除它们。


我想到了解决这个问题的方法,最终想出了我当前版本的代码,它使用了 splice 方法,但是 splice 方法是在我将其设置为状态之前使用的。在这里很明显:


        this.state.listArray.splice(i, 1);

        this.setState({

          listArray: this.state.listArray

        });

我的问题可以分解为三个子问题:

  1. 考虑到 React 状态应该是不可变的,上面代码的第一行是否改变了我的状态?这种做法不行吗?

  2. 我认为所有 React 状态只能在“setState”函数内更改,但我上面的第一行代码不在 setState 函数内,但它更改了 listArray 的状态。这怎么可能?

  3. 如果我的方法是改变状态并且不理想,你将如何制作删除功能以便它只删除一个条目并且如果有多个相似条目则不超过一个?


慕码人2483693
浏览 83回答 1
1回答

慕后森

是的,splice会影响它作用的数组,所以不要以这种方式使用。相反,您需要创建一个包含正确元素的新数组:this.setState({&nbsp; &nbsp; listArray: this.state.listArray.filter((el, idx) => idx !== i);});如果您只想删除第一个实例,则可以先与 a findIndex(尽管也indexOf可以在您的示例中使用)结合使用:delete(elem) {&nbsp; &nbsp; const idxToFilter = this.state.listArray.findIndex(el => el === elem);&nbsp; &nbsp; if (idxToFilter < 0) {&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; this.setState({&nbsp; &nbsp; &nbsp; &nbsp; listArray: this.state.listArray.filter((el, idx) => idx !== idxToFilter);&nbsp; &nbsp; });}这将在不修改旧数组的情况下创建一个新数组,这将导致任何对listArray更改做出反应的内容都被通知,因为引用已更改。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答