这两天学习react,撸了一遍文档后开始自己动手写点东西。
正好从朋友那得到灵感,写一个小例子。
这个东西是这样的,就是点击的这个节点就往它里面添加一个child。
于是乎!我想到的就是用自调函数,递归的思想来实现。
看一下他啥样:
解释一下:
~点击【添加根节点】按钮的时候就添加一个父id为空的节点
~点击每一个节点的时候就在它的内部添加一个child
这里为了方便,我的state就写的固定的 = 。=!(强行解释一波:主要锻炼思想),如下:
constructor(props){ super(props); this.state={ num:1,//用来记录新添加的id true_tree:[ {name:"本id:1;父id:",id:1,pid:"",child:[]} ] }; this.addTree=this.addTree.bind(this); }
页面上的渲染都是根据state里true_tree来决定的,所以,先看一下我是如何渲染的:
show(item){//用来根据true_tree里面的每一个child,循环出每一个子节点,传过来的参数item即为上一层的child let all = [];//创建一个容器,吧所有层的child都存在这里面一并返回 item.forEach((items,index) => {//因为传过来的child是一个数组,所以需要遍历 all.push( <div key={items.id} onClick={this.addTree.bind(this,items)}> {items.name} {items.child.length>0?this.show(items.child):""} </div> ); //递归渲染,如果有child就再执行一遍show方法,渲染出所有child }) return all;//将所有内容返回输出 }
可以看到,我对渲染出来的div都绑定了一个事件“addTree”,这个方法就是往state中的true_tree中添加节点信息的方法,来看一下:
addTree(item,e){//直接往树里面添加 e.stopPropagation();//防止事件冒泡,必须加上,不加就冒泡,会创建出重复id的节点 let true_tree = this.state.true_tree;//获取到当前的树结构 let sum = this.state.num+1;//新加的节点的id值 let newItem={name:"本id:"+sum+";父id:"+(item==="root"?"":item.id),id:sum,pid:item==="root"?"":item.id,child:[]};//新的节点的详细数据 if(item === "root"){//如果点击了的是添加根目录按钮(那个按钮传过来的是"root") true_tree.push(newItem);//则添加根节点 }else{ (function sort(t){//这是一个递归方法,如果根据pid在当前这层没找到他的父亲id,那么就去下一层找,还没找到就还去下一层 t.forEach((items,index) => { if(newItem.pid === items.id){ items.child.push(newItem);//如果找到了对应的父亲,就在这个父亲的child里面添加这个子节点 }else{ sort(items.child);//如果没找到调用本身去下一层找 } }) })(true_tree);//先从最高层开始根据pid寻找父亲id,所以穿true_tree } this.setState({//整个addTree方法结束,更新state num : sum, true_tree:true_tree }) }
当然,一个组件少不了render,一家人就是要整整齐齐的,所以就贴出来吧~:
render(){ return( <div> <button onClick={this.addTree.bind(this,"root")}>添加根节点</button> {this.show(this.state.true_tree)} </div> ) }
就这样,这个功能就实现了,其实就是一个用来控制数据的方法(addTree),一个用来控制渲染的方法(show)就完事了。
(当然,想让它变成一个可直接用的组件还需要修改,我发这一版的原因在于他还可以改成很多种组件,根据遇到的需求再改就可以了)
原文地址:https://www.cnblogs.com/sunchundong/p/9018418.html
时间: 2024-11-04 02:47:23