React实现点击删除列表中对应项

点击删除按钮,删除列表中对应项本来是React比较基础的应用,可是应用情况变得复杂了以后,我还真想了一会儿才搞定。

简化一下应用场景:点击新增按钮,增加一条输入框,点击输入框旁边的按钮,删除该输入框(不能删错了啊)。

先说第一种方法

问题刚上手,首先规划级别:一个输入框和对应删除按钮为一个子组件,整体为父组件即可方便处理。

注意的点:生成的一坨输入框是一个数组,为了准确删掉对应项,生成时要编号。点击删除按钮要反馈对应编号,然后进行删除。

现在的逻辑是:整个待展示列表(由子组件组成的数组)是个state,添加按钮会增加一个元素到这个state里面,添加的方法如下:

add(){
  var lists=this.state.lists;
  lists.push(<List key={this.state.lists.length} index={this.state.lists.length} delete={this.delete}/>);
  this.setState({lists:lists})
 }

注意一点,这个index属性是固定的,子组建生成后就固定了,这就为你未来挖了一个坑。

删除按钮当然就是从这个state列表里删除对应元素了,问题一来了,我怎么知道是第几个元素?一拍脑袋这还不简单,event.target 获取点击的标签,在标签上写个index属性告诉delete方法是第几个元素不就得了?试了发现不行,看看文档,event.target确实获取dom元素没毛病,但是index这个属性原生dom根本不承认啊,怎么办?data-index就行了,前面加 data- 就是dom承认的自定义属性了。

写完了又想起了两个方法,一个是在删除按钮绑定删除事件的时候,.bind(this,index),index是你准备删掉的是第几个或者表示出来你要删哪个就行。另一个是搞个闭包,就能把index参数传进去了(事件绑定一个立即执行的方程传入参数,该方程返回目标方程)。

第一个问题解决,删除的方法如下:

delete(e){
  var index=e.target.getAttribute("data-index");
  var lists=this.state.lists;
  lists.splice(index,1);
  this.setState({lists:lists})
 }

data-index告诉你要删除第几个元素,然后把它从state里踢出去就行了。这回掉进了一个真正意义上的坑:有时候删的不是对应的元素!乱套了!

好吧,我沉思了5分钟,想到了为什么:生成列表的时候index已经固定,但删除列表的时候我们只告诉他删除的是第index项!问题严重了,举个例子,有两项,index 0和1 你点0,好吧第0项删掉了,你再点1,疑?没反应了,因为你打算删除第1项,而列表中目前只有第0项(就是原来的第一项,原来的第0项删除后他就成了第0项)!这会导致各种乱套,考虑到生成列表的index是列表长度表示的就更乱了。

解决方式:delete方法里修改一行:

lists.splice(index,1,"");

好了,删除的元素我用空字符串代替,这样顺序和删除的项,还有以后添加的项的index都不会乱了,给自己点赞。到这里第一种方法实现了目标。

Code pen 地址:http://codepen.io/huanqingli/pen/dNyQez

完整代码:

class List extends React.Component {
 render() {
  return (<div><input type="text" defaultValue={this.props.index}/>
   <span onClick={this.props.delete} data-index={this.props.index}>X</span></div>)
 }
}
class Lists extends React.Component {
 constructor(props) {
  super(props);
  this.add=this.add.bind(this);
  this.delete=this.delete.bind(this);
  this.state={
   lists:[]
  }
 }
 add(){
  var lists=this.state.lists;
  lists.push(<List key={this.state.lists.length} index={this.state.lists.length} delete={this.delete}/>);
  this.setState({lists:lists})
 }
 delete(e){
  var index=e.target.getAttribute("data-index");
  var lists=this.state.lists;
  console.log(index)
  lists.splice(index,1);
  this.setState({lists:lists})
 }
 render() {
  return (<div>
   <span onClick={this.add}>添加</span>
   {this.state.lists}
   </div>)
 }
}
ReactDOM.render(
 <Lists/>,
 document.getElementById('lists')
);

这种方法有利有弊,所以我找到了第二种方法,具体情况择优使用。

第二种方法。总体来讲推荐这种方法。

在state里保存要展示的数据,在render里动态生成子组件组,然后添加删除都是操作保存数据的state,render里的子组件会自动刷新。这种方式应该是更贴近React思路的,用数据展现界面。如果你要展现一组数据,这种方法很自然,但如果展现的是一个动态的表单,稍微麻烦一点,但也可以做,而且我依然推荐用这种方式。

这种方法做个todolist就很简单,这里依然做上文的例子,稍微麻烦一点,也会理解的更深入一点。

整体结构和第一种方法一样,只不过这次state里面不是子组件,先用空字符串组成的数组代替,仅仅是为了render的时候知道有几个子组件而已。添加的时候也要push空字符串,等输入框输入数据后,更新state中的内容,做到数据和界面同步。

render子组件的部分:

{this.state.lists.map(function (item,index) {
    return <List key={index} index={index} delete={this.delete}/>
   }.bind(this))}

添加的方法变成:

add(){
  var lists=this.state.lists;
  lists.push("");
  this.setState({lists:lists})
 }

这就能跑了,这有个小坑,稍有不慎你发现你怎么删都是删列表的最后一项,其实数据操作没问题,关键是这个存在感比较低的key,必须特定项有给定的key你用动态的index他就懵了,不知道删哪个了,他就吧最后一个删了。废话不多说(该程序因为key键取值的问题有一个小问题):

Code pen 地址:http://codepen.io/huanqingli/pen/xgxNYN

整体代码:

class List extends React.Component {
 constructor(props){
  super(props);
  this.upData=this.upData.bind(this);
 }
 upData(e){
  this.props.upData(this.props.index,e.target.value)
 }
 render() {
  return (<div><input type="text" onBlur={this.upData} defaultValue={this.props.item?this.props.item:""}/>
   <span onClick={this.props.delete} data-index={this.props.index}>X</span></div>)
 }
}
class Lists extends React.Component {
 constructor(props) {
  super(props);
  this.add=this.add.bind(this);
  this.delete=this.delete.bind(this);
  this.upData=this.upData.bind(this);
  this.state={
   lists:[]
  }
 }
 add(){
  var lists=this.state.lists;
  lists.push("");
  this.setState({lists:lists})
 }
 delete(e){
  var index=e.target.getAttribute("data-index");
  var lists=this.state.lists;
  lists.splice(index,1);
  this.setState({lists:lists})
 }
 upData(i,x){
  var lists=this.state.lists;
  lists[i]=x;
  console.log(lists);
  this.setState({lists:lists});
 }
 render() {
  return (<div>
   <span onClick={this.add}>添加</span>
   {this.state.lists.map(function (item,index) {
    return <List key={item?item:index} index={index} delete={this.delete} upData={this.upData} item={item}/>
   }.bind(this))}
   </div>)
 }
}
ReactDOM.render(
 <Lists />, document.getElementById('lists')
)

这种方法经常也会有点小坑,也比较好解决。

总结:两种方法各有利弊,推荐第二种,符合REACT设计思路,但第一种有时候解决问题很方便。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • 基于React实现表单数据的添加和删除详解

    前言 最近在学习React,做了一个简单的Demo,用以自勉及和有需要的朋友们参考学习. 实现功能 在输入框中输入数据后,点击保存按钮,数据将会逐一显示在输入框下方,点击保存后显示的任何一条数据,该数据即可被删除. 实现思路 在开始实现之前,我们需要理清我们的思路,这样才能更好地去完成预定功能. 点击保存按钮时,输入框中的数据读取,可通过onChange绑定事件,获得输入框数据:e.target.value 自定义一个事件,输入数据后,点击保存按钮时,数据的存储操作交由该事件完成 当不断点击保存

  • 浅谈react.js 之 批量添加与删除功能

    最近做的CMS需要用到批量添加图片的功能:在添加文件的容器盒子内,有两个内容,分别是:添加按钮与被添加的选择文件组件. 结构分析: 被添加的组件,我们称为:UploadQiNiuFiles(七牛文件上传组件),含一个删除当前组件的删除按钮 添加按钮的事件 被添加组件存放的容器 做这个效果只需要明白三个方法的用途就OK: 直接绑定要删除组件的  deleteType(),它是调用删除index数量的方法  removeContent() //删除{qiniu}与{deleteQiNiu}内容,是把

  • ReactJs快速入门教程(精华版)

    现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和组件化的开发深深的吸引了我,下面来跟我一起领略ReactJs的风采吧~~ 文章有点长,耐心读完,你会有很大收获哦~   一.ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西

  • React实现点击删除列表中对应项

    点击删除按钮,删除列表中对应项本来是React比较基础的应用,可是应用情况变得复杂了以后,我还真想了一会儿才搞定. 简化一下应用场景:点击新增按钮,增加一条输入框,点击输入框旁边的按钮,删除该输入框(不能删错了啊). 先说第一种方法 问题刚上手,首先规划级别:一个输入框和对应删除按钮为一个子组件,整体为父组件即可方便处理. 注意的点:生成的一坨输入框是一个数组,为了准确删掉对应项,生成时要编号.点击删除按钮要反馈对应编号,然后进行删除. 现在的逻辑是:整个待展示列表(由子组件组成的数组)是个st

  • Python简单删除列表中相同元素的方法示例

    本文实例讲述了Python简单删除列表中相同元素的方法.分享给大家供大家参考,具体如下: 去除列表中重复的元素,非常简单,直接上代码: a = [11, 21, 3, 4, 3, 2, 5] b = list(set(a)) print(a) print(b) 运行结果: E:\Program\Python>d.py [11, 21, 3, 4, 3, 2, 5] [2, 3, 4, 5, 11, 21] 看到了吗,结果中确实没有了重复的元素.但是,同时,结果中的元素被按从小到大进行了排序! P

  • Python实现删除列表中满足一定条件的元素示例

    本文实例讲述了Python实现删除列表中满足一定条件的元素.分享给大家供大家参考,具体如下: 从列表中删除满足一定条件的元素. 如:删除一个列表中长度为0的元素,或者删除列表中同时是2和3的倍数的元素. 做过高级语言编程的人想当然的会认为"这很简单",可以如下面的方式来实现: for i in listObj: if(...): listObj.remove(i) 看下一个小例子和结果: a = [1, 2, 3, 12, 12, 5, 6, 8, 9] for i in a: if

  • python删除列表中重复记录的方法

    本文实例讲述了python删除列表中重复记录的方法.分享给大家供大家参考.具体实现方法如下: def removeListDuplicates(seq): seen = set() seen_add = seen.add return [ x for x in seq if x not in seen and not seen_add(x) ] 希望本文所述对大家的Python程序设计有所帮助.

  • 详谈python3中用for循环删除列表中元素的坑

    for循环语句的对象是可迭代对象,可迭代对象需要实现__iter__或iter方法,并返回一个迭代器,什么是迭代器呢?迭代器只需要实现 __next__或next方法. 现在来验证一下列表为什么支持迭代: x = [1,2,3] its = iter(x) # its = x.__iter__() print(type(its)) # print(its.__next__()) # print(its.__next__()) # print(its.__next__()) print(next(

  • python删除列表中特定元素的几种方法

    目录 前言 思路 方法1 方法2:使用while循环 方法3:for循环倒序删除空字符串 方法4:拷贝原列表 前言 题目如下: 给定一个仅包含大小写字母和空格 ’ ’ 的字符串 s,返回其最后一个单词的长度.如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词. 如果不存在最后一个单词,请返回 0 . 说明:一个单词是指仅由字母组成.不包含任何空格字符的 最大子字符串. 示例: 输入: "Hello World"输出: 5 思路 题目要求给一个字符串s,s仅包含字母和空格字符

  • javascript 删除数组中重复项(uniq)

    可以直接使用的代码:我们修正版 function unique(data){ data = data || []; var a = {}; len = data.length; for (var i=0; i [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 下面是进阶教程与说明,喜欢跟深入的朋友可以参考下.首先让我们看下 YUI 是如何处理的: 复制代码 代码如下: var toObject = function(a) { var o = {}; for (var i = 0; i

  • js删除select中重复项的实现代码

    删除select中重复项 body{ text-align:center;} div{ width:400px; background:#f1f5fa; margin:auto; border:solid 1px #BFC9DB; padding:10px;} h4{ } a{text-align:right; display:block; font-size:12px;} /*定义全局函数$*/ function $(id){ return document.getElementById(id

  • vue.js删除列表中的一行

    splice(index,num,item1,item2,...,itemX) 方法向/从数组中添加/删除项目,然后返回被删除的项目. 注:index--规定添加/删除项目的位置 num--要删除的项目数量 item--向数组添加的新项目 splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素. 如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组. (1)html代码: <div id="ap

  • python实现删除列表中某个元素的3种方法

    python中关于删除list中的某个元素,一般有三种方法:remove.pop.del: 1.remove: 删除单个元素,删除首个符合条件的元素,按值删除 举例说明: >>> str=[1,2,3,4,5,2,6] >>> str.remove(2) >>> str [1, 3, 4, 5, 2, 6] 2.pop: 删除单个或多个元素,按位删除(根据索引删除) >>> str=[0,1,2,3,4,5,6] >>&g

随机推荐