使用 proxy 實現的 mobx - dob 介紹

黃子毅發表於2017-09-06

一共有兩個套件:

dob

優勢,就是由於使用了 proxy,支援跟蹤不存在的變數,比如:

import { observe, observable } from 'dob'

const dynamicObj = observable({
    a: 1
})

observe(() => {
    console.log('dynamicObj.b change to', dynamicObj.b) 
})

// 現在要修改 b 了,b 之前不存在
dynamicObj.b = 2 // dynamicObj.b change to 2複製程式碼

很方便吧,實現了 mobx 夢寐以求的夙願,至今為止希望實現的 dob-react 已經被完美實現了。

dob-react

和 mobx-react 別無二致,優化點在於,不再區分 observer 與 inject,所有繫結與注入整合在一個裝飾器(因為有依賴追蹤,所以全量注入沒有效能問題,這很 DX)

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

@Connect
class App extends React.Component <any, any> {
    render() {
        return (
            <span>{this.props.store.name}</span>
        )
    }
}

ReactDOM.render(
    <Provider store={{ name: 'bob' }}>
        <App />
    </Provider>
, document.getElementById('react-dom'))複製程式碼

第二個優化點,在於不需要手動指定 @Observerable,所有變數自動開啟跟蹤。

完整用法

yarn add dob dependency-inject --save複製程式碼

store.ts:

import { inject, Container } from 'dependency-inject'
import { Action } from 'dob'

export class Store {
    name = 'bob'
}

export class Action {
    @inject(Store) store: Store

    @Action setName (name: string) {
        this.store.name = name
    }
}

const container = new Container()
container.set(Store, new Store())
container.set(Action, new Action())

export { container }複製程式碼

app.ts:

import { Provider, Connect } from 'dob-react'
import { Store, Action, container } from './store'

@Connect
class App extends React.Component <any, any> {
    componentWillMount () {
        this.props.action.setName('nick')
    }

    render() {
        return (
            <span>{this.props.name}</span>
        )
    }
}

ReactDOM.render(
    <Provider store={container.get(Store)} action={container.get(Action)}>
        <App />
    </Provider>
, document.getElementById('react-dom'))複製程式碼

相關文章