一款简单到极致的 React 数据流框架——Refast

Flux 是 React 框架的好伴侣。它优秀的单向数据流设计,使得数据的流向更加清晰,能帮助开发者更好的管理和调试组件的内部状态。Facebook 官方出 Flux 稍显冗杂,上手有必定的难度。javascript

下面是 Facebook Flux 的架构图。相信你们已经很熟悉了:
image.pngjava

Web API 或者 Web API Utils 等事件会发出一个动做 Action。通过派发器 Dispatcher,调用回调 Callbacks,修改数据层 Store。视图层 React Views 发现变化,反馈到视觉交互 User Interactions 上。这是一个循环往复的过程,最大的特色是数据单向流动。正是得益于此,前文所述的更好的管理和调试组件状态才能得以实现。react

这是一个很是完备、很是优秀的设计。那有没有一种方案,在囊括 Facebook Flux 优势的同时,又下降了学习难度,提升开发效率呢?不少开发者都进行了尝试,两年前就有人统计和分析过,不下二十余种。到如今,不少都已然夭折了,再也不维护。不少依然活跃着的或者后来涌现出来的,也愈来愈繁冗,愈来愈笨重。git

因此才有了 Refast。Refast 是 XUX 团队开发并开源的一款数据流框架。在调研了内部庞大的业务,进行了翔实的预演论证,博采推陈而来。github

Refast 的架构图正以下图所示:ajax

http://ata2-img.cn-hangzhou.img-pub.aliyun-inc.com/d864368d0dc423e14011420c1cb2a081.png

Refast 只有两部分,视图层 View 和 逻辑层 Logic。View 与其余的 Flux 并没有二致。有区别的是 Logic。 它是一些修改组件状态的函数(大致与 Action 相似,通常也称之为 Action)集合。大致是这个样子:架构

// 直接修改组件的状态
export function update(context, someState) {
  context.setState(someState);
}

// 异步请求后修改组件状态
export async function init(context, ...params){
  const asyncState = await window.fetch.apply(null, params);
  context.setState(asyncState);
}

咱们推荐使用 async/await 来处理异步操做。Logic 的第一个参数始终是 context。他封装了 setState、 getState、getProps 等几个通用的方法或者对象。app

  • context.setState 设置组件的 state, 用法与组件的 setState 相同框架

  • context.getState 获取组件当前的 statedom

  • context.getProps 获取组件当前的 props

在大部分场景下,你会对 context 按需扩展。好比将轻提示、警告对话框、数据请求、工具函数等挂在 context 下面。

import Refast from 'Refast ';
import { Message } from 'your-custom-message';
import { Dialog } from 'your-custom-dialog';
import { DB } from 'your-custom-ajax-handler';
import tools from 'your-custom-tools';

// 能够经过 use 自定义
Refast.use('fn', {
  message: Message,
  dialog: Dialog,
  DB,
  tools
})

扩展后的 context 会在每个 Logic 函数中生效。能够很轻易的调用他们:

async search(context, data) {
  try {
    await context.fn.DB.User.search(data);
    context.fn.message.success('员工信息获取成功');
  } catch(e) {
    context.fn.message.error(`员工信息获取不成功:${e.errorMsg}`);
  }
},

context 一个颇有用的特性,Refast 的灵性,一半源于此。那另外一半在哪里呢?就在咱们接下来要说起的 LogicRender 组件了。这也是 Refast 与其余数据流框架最大的区别之处。

LogicRender 集成了条件渲染、空数据和加载中等通用场景,同时,又能根据监听数据的变化,自主执行某些特定的逻辑。

一、好比,条件渲染。你能够给 LogicRender 设置一个名为 show 的 props。 当它不为真时,LogicRender 就不会渲染其子组件。

import { render } from 'react-dom';

render(){
  return (
    <LogicRender show={ this.state.show }>
    </LogicRender> 
  )
}

二、好比,通用 UI 的封装。根据你提供的状态来展现不一样的视图。

import { render } from 'react-dom';
import { LogicRender } from 'refast';

// 若是 isLoading 为 true,就展现 loading 状态
// 若是 isEmpty 为 true,则展现 empty 状态
render(){
  const { isLoading, isEmpty } = this.state;
  return (
    <LogicRender loading={ isLoading } empty={ isEmpty }>
    </LogicRender> 
  )
}

三、好比,执行 Logic。你能够给 LogicRender 指定一个 Logic,初始化时执行一次。若是设置了 awareOf,在当组件更新时,一旦 awareOf 发生变化,就会再次执行 Logic。

import { render } from 'react-dom';
const { workNo } = this.state;

render(){
  return (
    <LogicRender action={ 'update' } awareOf={{ workNo }}>
    </LogicRender> 
  )
}

Refast 的介绍到这里就结束了。上文基本上也就是 Refast 文档的绝大部份内容。简单到极致,就是咱们设计 Refast 的初衷。但愿 Refast 可以帮助到你们。

欢迎你们给咱们发issue或者加入钉钉群,一块儿讨论,让 Refast 能更快成长,更好的助力业务!