搜索
您的当前位置:首页正文

react+mobx:如何组织store之最佳实践

来源:二三娱乐

统一管理 Store

针对越来越多的store, 可以考虑使用 一个总 Store,保持对每个子 Store的引用。如有必要,可以在子Store中传入父Store,让子Store也可以访问到父Store。

import CountStore from './CountStore'
import ChangeNameStore from './ChangeNameStore'
class Store {
    constructor() {
        this.countStore = new CountStore()
        this.changeNameStore = new ChangeNameStore()
    }
}
export default new Store()

实践一

如上,简单创建的两个子Store。在需要使用数据的地方,import store即可, 看下面例子:

const ChangeName = (observer( ( {} ) => {
    return (
        <div className='Change'>
            <div>{store.changeNameStore.name}</div>
            <div className="buttons">
                <Button type="primary" className="btn" onClick={() =>
                    store.changeNameStore.changeName()
                }>change</Button>
            </div>
        </div>
    );
}))
export default ChangeName;

ChangeNameStore如下:

import {observable, action} from 'mobx'

class ChangeNameStore {

    @observable name = "sun"

    @action
    changeName() {
        if (this.name === "sun") {
            this.name = "wen"
        } else {
            this.name = "sun"
        }
    }
}

export default ChangeNameStore;

运行程序,点击按钮可以看到name改变。

这种方式引用方便,哪里用到store就哪里import。弊端就是如果store的层级越来越多,会导致代码难以编写。

实践二

官方参考redux,给出了Provider和inject组件,推荐使用DI方式去管理store,这也是我觉得最好的方式。
首先也是由一个stores保持有对所有子store的引用,接着使用Provider组件将stores传递给父组件。

import CountStore from './mobx/CountStore'
import ChangeNameStore from './mobx/ChangeNameStore'

const countStore = new CountStore();
const changeNameStore = new ChangeNameStore();

const stores = {
    countStore,
    changeNameStore,
}

class App extends Component {
    render() {
        return (
            <Provider {...stores}>
                <Home/>
            </Provider>
        );
    }
}

export default App;

如上,下面是怎么使用inject是自组件可以访问store。

const ChangeName = inject("changeNameStore")(observer( ( {changeNameStore} ) => {
    return (
        <div className='Change'>
            <div>{changeNameStore.name}</div>
            <div className="buttons">
                <Button type="primary" className="btn" onClick={() =>
                    changeNameStore.changeName()
                }>change</Button>
            </div>
        </div>
    );
}))

export default ChangeName;

推荐使用无状态组件,将需要的store直接传入组件,其他使用方法与之前无区别。
如此以来,无论store的层级有多少,针对单一功能组件原则, 可以将最小的store引入,方便管理。

Top