一个demo两张图带你走进React的世界(一)

发表于 2016-08-17
更新于 2024-05-23
分类于 技术专栏
阅读量 8897
字数统计 4302

前言

前端的世界真的是变幻莫测,如果使用著名的摩尔定律来说明前端的发展都感觉词穷的了。对于我这种刚涉足前端不到一年的菜鸟来说,还没有时间去掌握Angular,react已经开始红遍大江南北了,如今Vue.js大有赶超react的势头,所以在这个行业中,不时时刻刻保持学习更新知识的态度,那是不行的,不过我就喜欢这种不断学习新事物的感觉。废话了这么多,对于菜鸟的我大家也不能指望我可以给出多么深刻的理论知识,所以这篇文章只适合和我一样的菜鸟哦,大神就非喜勿喷哈。

1、react预备知识

学习react的开始莫过于学习官方网站的入门教程,我的demo也是在官网的入门教程指导下一步步地搭起来的,所以严重推荐到React入门教程上自己做一遍,顺利地话,童鞋们做完新手教程就几乎不用回来继续看我的瞎扯淡了。。。

如果还觉得意犹未尽,也可以参考下面几个大神写的入门篇:

  1. 阮一峰
  2. 雲霏霏

如果这时你还对我的这篇文章还感兴趣,那我真的是太谢谢你了。。。

2、demo的介绍

个人实现的demo是一个具有CRUD功能的table,代码的地址是:https://github.com/linxiaowu66/react-table-demo。

如何运行这个demo以及如何增删改查,可以参考工程的README.md文件。

从React的组件化思维来看待这个table,如下图:

react component

每一个框框都是一个所谓的React组件,一个组件套着另外一些组件。在最底层的组件本质就等价于一个最小不可分的单元,犹如生物世界中夸克,你可以利用这些很小很小的组件去搭建一个大规模的web应用。通过这一张图片,我们可以很清楚地看清每一个组件都是可测试的,可复用的,当我下次想再重新构建一张表格的时候,我们也许就只需要引用Table Box这个组件即可,其他的无须理会,这样的开发状态下是不是很爽!所以这种颠覆式地前端开发理念一下子就将众多的前端开发人员解放了,至此终于可以有了属于前端开发自己的库,再也不用老是重复一样的代码无数次。

接着我们再用一张图来看清整个react在没有redux之类的状态管理库的时候数据流的走向,通过这张图你或许会发现如果react没有redux或者flux的话是有多麻烦。

table的CRUD中React的数据流走向图:

react component

接下去的解释都是围绕该数据走向图来说的。

3、table组件的CRUD是怎么炼成的?

3.1、组件的介绍

为了实现表的增删改查,我们需要下面这些主要的组件:

  • MainWrapper:该demo中最大的组件,类似于CPU,处理以及分发所有的状态以及回调。
  • TableAction:该组件封装了CRUD四个小组件,用来传递MainWrapper的回调给CRUD四个小组件
  • TableBox: 该组件封装了table head组件和table body组件,同样是传递来自MainWrapper组件的回调以及数据。
  • TableContent: 该组件由一个个小的RowNode组件构成,RowNode组件便是一行行真正的数据的。
  • PopUpBox:该组件是一个弹出框组件,在需要添加或者修改的时候,这个组件会显示出来。

3.2、 组件的设计

习惯于从最小的组件开始设计,所以我们先从最小的组件说起。

3.2.1、RowNode组件

该组件的表现形态大致如下图中的灰白相间的每一行:

所以包含了一个复选框、两列数据。

那我们就知道这个RowNode组件的大致代码是:

var RowNode = React.createClass({
  render: function(){
    return (
      <tr>
         <th>
          <input type='checkbox' name='item' />
        </th>
        <td>{this.props.fruitName}</td>
        <td>{this.props.color}</td>
      </tr>
    )
  }
});

接下去考虑复选框的行为。当我们选中某一行的时候,该复选框应该会被打个勾的。所以我们需要一个props来切换这个选中状态,谁来触发切换呢?

根据React中文文档的表单组件,使用onChange事件来监听切换,因为每一行的勾选的状态对于之后的编辑和删除操作时相关联的,所以在切换的时候还需要通知一个组件--那就是MainWrapper。这就是为什么在图2中MainWrapper会维护一个叫做editData的状态。

所以我们改动代码为:

var RowNode = React.createClass({
  toggleChange: function() {
    this.props.handleChecked({index: this.props.index, isChecked: !this.props.isChecked});
  },

  render: function(){
    return (
      <tr>
         <th>
          <input type='checkbox' name='item' checked={this.props.isChecked} onChange={this.toggleChange} />
        </th>
        <td>{this.props.fruitName}</td>
        <td>{this.props.color}</td>
      </tr>
    )
  }
});

MainWrapper组件的回调中可以带有参数,因为我们需要知道是哪一行以及选中状态,所以传递的参数如代码中所示。

这种带有回调形式的传参是依据React中文文档--组件间的通信来设计的。

3.2.2、TableContent 组件

既然有了RowNode组件,那么我们还需要一个大的组件将其包含起来,并且这个组件还需要传递刚才RowNode组件使用的handleChecked回调函数。因为RowNode组件的个数是取决于上层组件的data值,所以使用一个map来循环:

var TableContent = React.createClass({

  render: function(){
    var rowNodes = this.props.data.map(function(tableList, i){
      return (
        <RowNode fruitName = {tableList.fruitName}
                 color={tableList.color}
                 key={i}
                 index={i}
                 isChecked = {tableList.checked}
                 handleChecked = {this.props.handleChecked}
        />
      )
    }.bind(this));

    return (
      <tbody className='tableBody'>
      {rowNodes}
      </tbody>
    )
  }
})

当你使用相同的组件多次的时候,记得加上一个key的属性,这个关键字可以帮助React优化它自己的虚拟DOM的渲染。具体参考React中文文档--动态子级

后面的几个组件放在第二篇来讲解:一个demo两张图带你走进React的世界(二)

公众号关注一波~

微信公众号

关于评论和留言

如果对本文 一个demo两张图带你走进React的世界(一) 的内容有疑问,请在下面的评论系统中留言,谢谢。

网站源码:linxiaowu66 · 豆米的博客

Follow:linxiaowu66 · Github