React 导读(三)

前言

React 导读(一)
React 导读(二)javascript

在以前 2 篇文章中中学习到了写第一个 Web 组件以及经常使用的生命周期函数的使用,这篇文章将继续以前的目录,开始新的知识点补充:css

  1. [x] React 如何编写 Hello World!
  2. [x] React 中三个最基础、最重要的东西
  3. [x] React 中的 JSX
  4. [x] 你的第一个 Web 组件
  5. [x] React 中最开始须要关注的生命周期
  6. [x] React 一个组件集合的简单交互
  7. [x] React 开始一个项目的一点建议
  8. [ ] React 简单的项目结构组织

这篇文章主要会介绍第六、7的知识点。html

六 & 7、React 一个组件集合的简单交互以及开始一个项目的一点建议

为何要将六、7合在一块儿写呢?不是由于想偷懒...实际上是脱离一个场景和合适的开始去规划组件等设计都是不合理的,多多少少都有点交集,因此将这 2 点融合在一块儿是更利于学习和理解的,到这里就已经不是太基础的内容了,基本上代码量会有所提升,可是分析依然会很细致。前端

这里用一个简单的表格的添加删除编辑搜索四个功能来做为实例吧。
由于这应该是平常开发过程当中遇到过程最多的,我将参考 bootstrap-table 的方式来开发一个简单的表格组件和约定配置来作,感受比较自由,若是你动手能力好且业务稍大和复杂能够参考 antd 设计规范来实现,目前市面上应该蚂蚁这套用的比较多,可是这并不意味着咱们就必定是按照他来作,实际项目不复杂的状况是可使用更简单的方式。java

作这个开始以前,首先要假设一点场景和基本需求,这样才能带着去思考如何实现以及更接近需求目标。react

(1) 场景git

为了更清晰的安排年前年后的工做和值班,如今要对过年期间人员请假的状况进行统计,而且进行一个简单的管理。github

(2) 功能性需求编程

  • 添加员工的请假信息
  • 展现添加的员工请假的列表
  • 可以对信息进行修改
  • 可以删除添加的信息,因为不可恢复,因此须要一个提示
  • 可以根据员工的名字进行搜索

简单描述了一下,其实就以前说的几个功能。json

图片描述

最后作出来的效果以下(=.=没有设计,对齐就行哈):

图片描述

看以前能够下载源代码对照着看,不过代码可能会不断修改 BUG,哈哈~有 BUG 不要虚,没有 BUG 咱们可能就失业了。
源码-GitHub

(3) 准备工做

  1. 整理须要用到的技术
  2. 开发要用的基础 UI 组件
  3. 看下 bootstrap-table 的基本设计
  4. 搭建项目目录

1. 须要用到的技术
须要用到的技术:React/ES6, CSS 便可

2. 基础 UI 组件
根据咱们这里的功能来看,咱们只须要下面这几个基础组件便可:
Button, Dialog, Input, Table, Radio

在这个例子项目里面,组件的划分结构以下:

图片描述

为何要这样划分呢?

  • 基础组件:其实这个是每个项目都须要的,若是说过小的项目不须要其实大多数是考虑掉了项目的迭代周期的考量以及之后代码的可复用性,顾名思义,基础组件就是你要在之后的组件编写过程当中须要依赖的最基础的组件,基本是只负责 UI 层面的职责,固然你还可以再剥离,这里就不太展开了,知道这一层是为了之后写组件可以有本身的基础组件便可。
  • 业务组件、模块组件:在咱们开发好基础组件事后,其实这些基础组件是不具有任何业务价值的,好比有了业务设计稿后,咱们须要针对业务而后编写业务中公用的组件或者封装使用操做2次的组件代码,造成一个可复用的业务组件或者业务模块类型的组件。好比我这里会将每一个模块用到的模块标题封装成一个 ModTitle 组件,这样之后修改这里样式的时候所有就在一个地方修改,或者在业务系统上会有 Layout 相关的布局组件需求,再好比系统中表格整个一块的需求,包含搜索、头部操做按钮、数据展现表格,这三者可以进行一个通用性的封装来造成业务模块上的表格使用组件,增长编写模块的效率,固然这里我并无封装,由于封装和重构并非软件初始开发更应该注重的,而是遇到第二次的时候再反过来思考如何避免重复或者让组件内部封装。
  • 展现组件、容器组件:这一层就是网上流行的展现型组件、容器组件的一层,我这里划分主要是跟具体业务功能有关系的一层。因为我这里没有 react-router,因此复杂度会低一些,后面有时间也能够介绍。

3. bootstrap-table 生成表格的方式

能够查看 github-bootstrap-table 的使用例子来看下使用方式,这里我用它作例子并非说此库彻底好或者很差,而是之前项目用了 bootstrap-table 而后就模仿了 columns 配置的方式,对于它 API 设计的其余部分暂时没采用。
表格组件实际上是管理类系统很核心的部分,一是用的多,二是自己也比较复杂,封装太死缺乏灵活性,封装太简单缺乏效率,种类也比较多。大致上我会采用字段进行配置的方式,具体看后面的代码和分析。

4. 项目的目录规划
上面介绍了一些概念性的东西,那么项目主要的目录单独提一下,这里的项目目录不适合大型项目,可是须要一个这个过程,来理解每一项的意思以及为何咱们还须要其余技术来解决你遇到的问题,堆技术的作法是不可取的,至少在不疯狂 KPI 模式的状况下。

├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
├── server // 网站后端的目录,这里咱们不须要关系
├── src // 前端的源代码目录
│   ├── App.js // App 的入口组件
│   ├── apis // API 请求层的相关文件,Ajax 的方法也是须要适配的,好比常见的拦截器作法
│   ├── app.css
│   ├── assets // 一些静态资源
│   ├── components // 包含了业务组件、模块组件、展现组件,这里项目较小的时候不须要划分太细,可是要有这样的分层来组织代码
│   ├── containers // 容器组件,主要的反作用等逻辑组件,基本上是数据初始化、维护一个较顶层的数据入口
│   ├── index.css
│   ├── index.js // 网站的入口 JS 文件,主要是负责组件挂载到 DOM,或者你也能够作一些全局注入的一些操做
│   ├── normalize.css
│   ├── registerServiceWorker.js
│   ├── smarty // 基础组件的目录,这里我叫它 smarty,命名空间使用 st-,这个随你高兴
│   ├── stores // 数据操做的主要聚焦地方,每个 Store 都能是一个事件订阅者,用于链接 React View 组件
│   └── utils // 一些工具辅助函数,目前我这里没有使用,真实项目确定会用上的

(4) 开始思考要如何开始写代码

  1. 须要一个 React 的容器组件来渲染我想要的一个功能模块;
  2. 功能模块的数据须要一个地方进行管理。

要解决第一个问题,假设咱们的容器组件叫 EmployeeManage,那么在最外层的 App 组件中应该声明要渲染它,代码就会是这样:

class App extends Component {
    render() {
        return (
            <div className="App">
                <EmployeeManage />
            </div>
        );
    }
}

好了,假设这样会出现最初的那个效果图的样子,那么数据并不想写的太过于零散,因此我定义了一个 Store 类进行管理,为何是类呢?如今不是流行 Redux 之类函数式的么?一是在最开始学习的时候增长太多技术栈心累,二是不必定要用 Redux 咱们才能写好 React,三是感受也不太必要就咱们目前的需求来看,四是我就想最初简简单单的。
可是如今咱们是数据驱动方式的编程,数据变了来通知 React 的 state 变了而后 React 去帮咱们作视图的更新,因此,咱们的 Store 得是一个基于事件的类,要有事件应该有的特征:监听。因此最后我须要一个 EmployeeStore

// 用下自带的,你也能够本身实现一个简单的
import EventEmitter from 'events';
import assign from 'object-assign';

const state = {};

const EmployeeStore = assign({}, EventEmitter.prototype, {
    // 把容器组件的 this.state 在这里管理
    getState() {
        return state;
    }
});

原始是原始了一点,可是应该很好理解,那就是个人 EmployeeStore 拥有了 EventEmitter.prototype 的东西,好比经常使用的 on(), off(), emit() 等方法来实现事件特性。
而后咱们须要把 EmployeeManageEmployeeStore 链接起来,最简单的链接像这样子:

class EmployeeManage extends React.Component {
    constructor() {
        super();
        // 看这里
        this.state = EmployeeStore.getState();
    }
}

链接了这个基础的东西,咱们的 EmployeeStore 不是还能够订阅事件么?而后数据修改了咱们就触发一下订阅的事件去告诉 EmployeeManage 而后经过 this.setState 去更新视图便可,整个关系以下:

图片描述

看图可能就更直观的知道数据和组件之间的关系了,用过 Flux 可能能够发现还比较像,可是这是两个不一样的理念,我这里只是一个最基础的事件系统,因此会特别简单。

咱们如今来订阅一个名为 updateList 的事件,用来表示表格中须要展现每条数据。咱们须要在 EmployeeManage 中加入下面的代码:

componentDidMount() {
    EmployeeStore.on('updateList', this.handleUpdateList);
}

componentWillUnMount() {
    EmployeeStore.off('updateList', this.handleUpdateList);
}
    
handleUpdateList(list) {
    this.setState(prevState => {
        return {
            list: list,
        };
    });
}

这三个方法能跟上面的图对应一下,就对应上了 EmployeeManageComponent,那么咱们的 Store 须要怎么作呢?

getList() {
    // API 请求列表数据的方法,返回一个 Promise
    EmployeeApi.get().then(result => {
        if(result.status === 200) {
            // 恰好,就通知了 EmployeeManage 说我数据获取成功了,能够更新视图了
            this.emit('updateList', result.data);
        }
    });
},

以上就完成了链接工做了,基本上剩下的就是码代码,往上累积功能。先写到这里吧,太长看着也累,分一下章节吧~其实架子已经差很少了,剩下的就是写功能点了。若是以为看文章太慢能够直接看源码可能会更快更直接一点,没有数据层,其实并非太好,先理解视图和关系吧。

相关文章
相关标签/搜索