dingDang-2.0

一张图了解dingDang数据流向

《dingDang-2.0》

概念

我们将dingDang定义为一个React数据层产品,因为在dingDang设计之初,我们就抱着用户的开发体验放在第一位的理念。
我们希望在简单的业务场景下,你可以尽可能的用直截了当的方式来写代码,而不是去建一大堆的JS文件,而当你的业务逐渐
的复杂的时候,你又可以在你简单的代码上很轻松的进行扩张、模块化。

起初,我们是很认同Redux的全局Store的概念的,但是当我们的项目成长到一定规模时,我们发现整个研发团队对于成员的
职业素质要求很高,否则将会写出很糟糕的代码,导致整个Store混乱不堪,这无形之中增加的研发团队的成本。

通过我们自身的项目总结,我们发现在大多数的业务场景下,其实我们需要的是即用即开、用完即毁的Store 。
同时在少数情况下,我们会遭遇到多个页面之间共享一部分数据的情况,我们将这种情况称之为场景,也就是我们下面将要描
述的数据场景化概念,这与Redux的全局Store在抽象的层面上是完全不同的概念,在代码层面上则是粒度大小的区别。

能力积木化


dingDang本身并不具备多少能力,我们只定义的数据流动的沟壑,以及在这些沟壑中设立了多个岗哨,我们将这些岗哨对外开
放,你可以在岗哨上做些什么,通俗一点也就是插件机制。

我们默认提供了两个插件:
  • injector(注射器):

    主要定义了对页面或组件的props注入规则,值得注意的是,该插件是必须的,否则dingDang几乎什么也干不了。
    
  • rules(规则):

    该插件主要针对store中的state数据提供一些数据校验机制 , 或者在表单场景下比较适用。
    

数据场景化

我们对数据场景化的定义是:

用户在执行某一个完全的业务行为时,需要在多个页面之间来回切换 ,并且在多个页面中
都是针对同一份业务数据进行操作。那么我们将这多个页面称之为:【场景】。而多个页面共享数据这种行为称之为:【数据场景化】

在实际落地的时候,数据场景化往往会因为用户的操作习惯、dingDang的应用平台等出现各式各样的问题。

例如:按照我们定义的数据场景化的情况下,如果用户在一个由5个页面组成的场景中进行某些行为动作,当用户已经进行到最后一个
页面时,突然点击了浏览器的刷新,那么可能会将前4个页面的所有数据丢失,也就是说我们的场景需要一个持久化的过程。

在最初,我们试想着将数据相对持久化在浏览器的sessionStorage中,但是随即我们发现,这样我们将会抛弃了react-native这个玩意,
所以干脆我们就将数据持久化的过程交与你来完成,根据你的实际业务场景选出适合自己的持久化方案。

目前,我们仅仅只支持在全局配置一套持久化方案,我们深知这是觉得不能满足某些业务需求的,在稍后的版本中,我们会提供针对Store级别
配置独立的持久化方案,如果Store中没有配置持久化方案,那么默认采用全局的持久化方案。

dingDang 由简入深

认识dingDang

Store(仓库、商店)

每一个Store中都存储了页面相关的状态(state)、用户的行为动作(reducer、effect)、以及第三方插件补充的部分机制(例官
方插件:rules),Store可以被装饰器进行装饰,装饰之后的Store可以被渲染到页面上、也可以被多个页面共享。

namespace(必要)

每一个Store都必须具备该字段 , 该字段标示Store的唯一性。

state(必要)


每一个Store都必须具备该字段 , 该字段用来存储页面所需的状态信息(也就是数据)

reducer(非必要)

reducer内建议都写纯函数,避免第三方的不可靠元素 , reducer 是唯一可以直接去修改state的入口,每一个reducer 最终都必须返回一个全新的state ,
当然,你返回的state 并不一定就是最终页面上所体现出来的 , 因为当你的state 返回出去之后还有可能被一部分拦截器进行拦截,对你的数据进行修改,
所以请留意自己所配的插件信息。

effect (非必要)


effect为副作用函数聚集地 , 一般来说, 与服务端进行ajax交互的代码我们都适应于写在这里,effect内无法直接对state进行修改 , 不过我们提供了
调用reducer 的函数 ,也即是说在effect中如果你想修改state , 那么你应该通过reducer进行中转。

系统函数

execReducer执行器

此函数为高阶函数 ,我们会在页面级的props 以及每一个effect中注入这个执行器,以便你可以对state进行某些操作。
每一个reducer都会返回一个Promise对象 ,如果Promise处于resolve的状态的话,那么我们会返回最新的全量的state,
否则我们会抛出异常!
调用方式如下:
    execReducer('reducerName')(payload)

execEffect执行器


此函数为高阶函数 ,我们会在页面级的props 以便你可以在页面中方便的调用effect
每一个effect都会返回一个Promise对象,在每一个effect中我们都将resolve、reject暴露出来,以便你控制你自己的业务逻辑。
调用方式如下:
    execEffect('effectName')(payload)

onChangeState函数


该函数是我们贴心的为你提供的直接修改state的函数, 上文中我们提到过,store中的reducer是非必要的,那么在没有reducer 的情况下我们怎么修改
state 呢? 这个时候就可以使用由系统提供的onChangeState , 实际上在dingDang的内部,即使你没有写reducer ,我们也会动态的生成一个,并且
默认情况下我们会为reducer挂载一个名称为:[onChangeState${random}]的函数,而这个函数经过我们的转换,就是你看到的onChangeState函数了,
我们会在页面级的props以及effect中为你注入这个函数。
调用方式如下:
    onChangeState({name:'张三'})

装饰器

Page

当业务场景仅仅局限于单页面时使用。

ScenePage


场景装饰器,当使用该装饰器时,多个页面如果采用的namespace相同的store,并且是连续相互之间跳转,那么会共享store,被认为是一个场景。

Component

被装饰者被标示为一个组件(非页面级入口),使用该装饰器的话,那么该组件必须被一个 Page装饰器说装饰的页面使用, 否则会报错。

插件

在这里我们暂时不开放插件的相关拦截点,主要介绍一下官方目前提供的两个插件。

injector (注射器)


该插件主要用来协助装饰器将Store注入进view中,你只需要知道没有这个插件,你的dingDang将无法正常运行起来即可,所以该插件是必要配置的,当然,
如果你自己实现了一套注射器,那么你可以将此插件替换掉。

rules (规则)

该插件主要定义了state中每一个字段的校验规则 , 具体的校验过程在 每一次执行完reducer之后进行校验。
先看一个demo。

const store = {
    namespace:'demoStore' ,
    state:{
        name:''
    },
    rules:{
        name:[
            {
                validate:(state , name) => name.length < 8,
                error:'用户名的长度不能大于8',
                merge:true
            }
        ]
    }
}
rules中的每一个key都要与state一一对应,以便插件识别是校验哪一个字段。
  • validate(必要) 校验函数

  • error(必要) 错误提示

  • merge(非必要,存在默认值) 如果发生了错误,是否依然合并进state , 该字段默认为true

使用

npm install 0.2.4-alpha --save
    原文作者:ityuany
    原文地址: https://segmentfault.com/a/1190000009986251
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞