专栏名称: 前端外刊评论
最新、最前沿的前端资讯,最有深入、最干前端相关的技术译文。
目录
相关文章推荐
商务河北  ·  经开区“美•强•优”三重奏 ·  16 小时前  
奇舞精选  ·  从 DeepSeek 看25年前端的一个小趋势 ·  昨天  
奇舞精选  ·  从 DeepSeek 看25年前端的一个小趋势 ·  昨天  
前端早读课  ·  【第3452期】React 开发中使用开闭原则 ·  2 天前  
51好读  ›  专栏  ›  前端外刊评论

面向未来的前端数据流框架 - dob

前端外刊评论  · 公众号  · 前端  · 2017-11-03 21:51

正文

我们数据技术产品部有一部分只需要兼容最新版 chrome 对外产品,以及大部分对内产品,都广泛使用了 dob管理前端数据流,下面隆重介绍一下。

dob 是利用 proxy 实现的数据依赖追踪工具,利用 dob-react 与 react 结合。

dob 的核心思想大量借鉴了 mobx,但是从实现原理、使用便捷性,以及调试工具都做了大量优化。

特征

  • ✅ 支持

  • ❌ 不支持

  • 📦 生态支持

  • 🤷 不完全支持

功能 redux mobx dob
异步 📦redux-thunk 等
可回溯 📦 mst
分形 🤷 replaceReducer
代码精简 📦 dva 等
函数式 🤷 🤷
面向对象 🤷
Typescript 支持 🤷
调试工具
调试工具 action 与 UI 双向绑定 🤷
严格模式
支持原生 Map 等类型
observable 语法自然度
store 规范化 🤷

从依赖追踪开始

dob 自己只实现了依赖追踪功能,其特性非常简单,如下示意图+代码所示:

  1. import { observable, observe } from "dob"

  2. const obj = observable({ a: 1, b: 1 })

  3. observe (() => {

  4.    console.log(obj.a)

  5. })

一句话描述就是:由 observable 产生的对象,在 observe 回调函数中使用,当这个对象被修改时,会重新执行这个回调函数。

与 react 优雅结合

那么利用这个特性,将 observe 换成 react 框架的 render 函数,就变成了下图:

  1. import { observable, observe } from "dob"

  2. import { Provider, Connect } from 'dob-react'

  3. const obj = observable({ a: 1 })

  4. @Connect

  5. class App extends React.Component {

  6.    render() {

  7.        return (

  8.            <span onClick={() => { this.props.store.a = 2 }}>

  9.                {this.props.store.a}

  10.            span>

  11.        )

  12.    }

  13. }

  14. ReactDOM.render(

  15.     <Provider store={obj}> <App/> Provider>

  16. , dom)

这正是 dob-react 做的工作。

上面这种结合随意性太强,不利于项目维护,真正的 dob-react 对 dob 的使用方式做了限制。

全局数据流

为了更好管理全局数据流,我们引入 action、store 的概念,组件只能触发 action,只有 action 内部才能修改 store:

由于聚合 store 注入到 react 非常简单,只需要 Provider @Connect 即可,所以组织好 store 与 action 的关系,也就组织好了整个应用结构。

那么如何组织 action、store、react 之间的关系呢?对全局数据流,dob 提供了一种成熟的模式:依赖注入。以下是 可维护性良好模式

  1. import { Action, observable, combineStores, inject } from 'dob'

  2. import { Provider, Connect } from 'dob-react'

  3. @observable

  4. export class UserStore {

  5.    name = 'bob'

  6. }

  7. export class UserAction {

  8.    @inject(UserStore) private UserStore: UserStore;

  9.    @Action setName () {

  10.        this.store.name = 'lucy'

  11.    }

  12. }

  13. @Connect

  14. class App extends React.Component {

  15.    render() {

  16.        return (

  17.             <span onClick={this.props.UserAction.setName}>

  18.                {this.props.UserStore.name}

  19.            span>

  20.        )

  21.     }

  22. }

  23. ReactDOM.render(

  24.    <Provider {

  25.         ...combineStores({

  26.            UserStore,

  27.            UserAction

  28.        })

  29.     }>

  30.        <App />

  31.    Provider>

  32. , dom)

一句话描述就是:通过 combineStores 聚合 store 与 action,store 通过 inject 注入到 action 中被修改,react 组件通过 @Connect 自动注入聚合 store。

局部数据流

对于对全局状态不敏感的数据,可以作为局部数据流处理。

@Connect 装饰器如果不带参数,会给组件注入 Provider 所有参数,如果参数是一个对象, 除了注入全局数据流 ,还会把这个对象注入到当前组件,由此实现了局部数据流。

PS: Connect 函数更多用法可以参考文档: dob-react #Connect

结构如下图所示:

  1. import { Action, observable, combineStores, inject } from 'dob'

  2. import { Provider, Connect } from 'dob-react'

  3. @observable

  4. export class UserStore {

  5.    name = 'bob'

  6. }

  7. export class UserAction {

  8.    @inject(UserStore) private UserStore: UserStore;

  9.    @Action setName () {

  10.        this.store.name = 'lucy'

  11.    }

  12. }

  13. @Connect(combineStores(UserStore, UserAction))

  14. class App extends React.Component {

  15.    render() {

  16.        return (

  17.            <span onClick={this.props







请到「今天看啥」查看全文