这两天学习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)就完事了。

(当然,想让它变成一个可直接用的组件还需要修改,我发这一版的原因在于他还可以改成很多种组件,根据遇到的需求再改就可以了)

基于react可无限向内部添加节点的tree的更多相关文章

  1. 基于react实现无限分级菜单

    在开发CMS(内容管理系统)系统时,一般都会用到一个侧边栏或者顶部的二级或者三级菜单,当点击或者鼠标悬浮时,菜单能够随之展开或收起. 本文纯粹为了练习一下react,因此我会在react环境下实现这么 ...

  2. 放弃antd table,基于React手写一个虚拟滚动的表格

    缘起 标题有点夸张,并不是完全放弃antd-table,毕竟在react的生态圈里,对国人来说,比较好用的PC端组件库,也就antd了.即便经历了2018年圣诞彩蛋事件,antd的使用者也不仅不减,反 ...

  3. 实例讲解基于 React+Redux 的前端开发流程

    原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...

  4. React-Native(三):React Native是基于React设计的

    React Native是基于React js设计的. 参考:<React 入门实例教程> React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript ...

  5. Centos7.5基于MySQL5.7的 InnoDB Cluster 多节点高可用集群环境部署记录

    一.   MySQL InnoDB Cluster 介绍MySQL的高可用架构无论是社区还是官方,一直在技术上进行探索,这么多年提出了多种解决方案,比如MMM, MHA, NDB Cluster, G ...

  6. 基于 React 实现一个 Transition 过渡动画组件

    过渡动画使 UI 更富有表现力并且易于使用.如何使用 React 快速的实现一个 Transition 过渡动画组件? 基本实现 实现一个基础的 CSS 过渡动画组件,通过切换 CSS 样式实现简单的 ...

  7. 警惕rapidxml的陷阱:添加节点时,请保证变量的生命周期

    http://www.cnblogs.com/chutianyao/p/3246592.html 项目中要使用xml打包.解析协议,HQ指定了使用rapidxml--号称是最快的xml解析器. 功能很 ...

  8. JQuery--Ajax 异步操作 动态添加节点 (新人试水,求支持)

    异步操作动态添加节点,导致在代码中给添加的节点全局绑定事件或者获取元素无效,上代码: $(function () { var IP = '...'; // 页面中的默认编号起始值 和 公用IP前缀 s ...

  9. 基于 React + Webpack 的音乐相册项目(下)

    上一篇我们完成了音乐相册里面的播放图片的功能,这一篇主要完成的是音乐相册里面的音乐播放器功能.最终让我们基于 React 的音乐相册图文并茂.有声有色. 我们主要从以下几个部分来展开: 数据准备 进度 ...

随机推荐

  1. django filter or 多条件查询

    功能:django中实现多条件查询 或关系: from django.db.models import Q return qs.filter(Q(notice_to_group__contains=' ...

  2. CentOS-07安装Redis学习笔记

    CentOS-07安装Redis 下载 http://download.redis.io/releases/redis-3.0.0.tar.gz 安装第一步:将下载的Redis源码包上传大奥Linux ...

  3. Android横竖屏切换生命周期变化

    1. AndroidMenifest没有设置configChanged属性. 竖屏启动(横屏启动相同): onCreate -->onStart-->onResume 切换横屏: onPa ...

  4. labellmg的使用

    ---恢复内容开始--- 在powershell环境下进入到labelImg解压后的文件,我这里是D:\labelImg-master\labelImg-master 执行命令: pyrcc5 -o ...

  5. git tag 查看标签列表、切换标签

    1.查看标签列表 git tag 2.切换标签(需要指定分支 test 为分支.v0.17.7 为标签版本) git checkout -b test v0.17.7

  6. 2. 2A03简介

    2A03简介 1.CPU 1.1 内部寄存器 1.累加寄存器A(Accumulator):8位寄存器,用于同算术逻辑单元(ALU)共同完成各种算术逻辑运算,它既为ALU提供原始操作数又担任存放ALU运 ...

  7. 分布式之redis

    正文 1.为什么使用redis 分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发.当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有 ...

  8. Vue element 分页

    Vue单页面,有一个带分页的表格,表格内数据关联页码,套路如下: 代码如下: <div class="c-table-list auth-list m-bottom-20"& ...

  9. Python实现对CSV文件的读写功能

    我们要处理csv文件,首先要的导入csv模块 import csv #读取csv文件def readCsv(path): #传入变量csv文件的路径 list=[] #定义一个空列表 with ope ...

  10. clean-room 洁净室软件工程

          众所周知,软件工程的主要目的是提高软件的开发效率和软件质量.近年来发展起来的洁净室软件工程(cleanroom software engineering)提出了用统计的质量控制方法管理软件 ...