摆脱redux繁琐操作,搭建mobx框架

栏目: JavaScript · 发布时间: 6年前

内容简介:MobX 是透明的函数响应式编,它主要优点使得状态管理变得简单和可扩展(这一点接下来我会简单的对比一下redux);两者都是状态管理库,用来管理应用的内部状态,所以在我们项目中,完全可以相互替代,我简单的对比一下开发成本:这里我以标准的项目实践对比,在我们日常项目开发中,采用redux库,下图是我们一个业务组件的目录结构

MobX 是透明的函数响应式编,它主要优点使得状态管理变得简单和可扩展(这一点接下来我会简单的对比一下redux);

摆脱redux繁琐操作,搭建mobx框架
React 和 MobX 是一对强力组合。React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而MobX提供机制来存储和更新应用状态供 React 使用。官网传送

redux和mobx对比

两者都是状态管理库,用来管理应用的内部状态,所以在我们项目中,完全可以相互替代,我简单的对比一下开发成本:

这里我以标准的项目实践对比,在我们日常项目开发中,采用redux库,下图是我们一个业务组件的目录结构

摆脱redux繁琐操作,搭建mobx框架
摆脱redux繁琐操作,搭建mobx框架

通常我们如果我们需要通过一个接口获取列表数据,需要在多个文件中定义一整套变量,项目业务复杂开发不规范,就会出现以下现象:

摆脱redux繁琐操作,搭建mobx框架

反过来,我们看下重构之后,采用mobx的文件目录结构

摆脱redux繁琐操作,搭建mobx框架

具体实现方式,下文会详细介绍,以上仅做简单对比!

开始搭建mobx项目

首先,该项目是采用webpack4打包器,对webpack配置不熟悉的同学,可参考一下掘金上Better_man同学的优秀讲解 webpack4.x最详细入门讲解

现在完事具备,只欠mobx,开始我们的mobx之旅~

Step 1: 安装依赖文件

npm i mobx mobx-react -D
复制代码

Step 2: 组件以及模块划分

摆脱redux繁琐操作,搭建mobx框架

定义好目录结构以及模块拆分很重要,使得我们在开发过程中思路清晰,代码整洁;

Step 3: 划分领域store,并定义可观察的状态

我们在store文件夹下新建,movieStore.js文件,如下图

摆脱redux繁琐操作,搭建mobx框架

接下来,如何定义可观察的状态呢,我们看代码:

import {observable, action, computed, runInAction} from 'mobx';
import Api from '../api/movie';

export class movieStore {
    @observable movieList = [];
    @observable state = 'pending';

    constructor(rootStore) {
        this.rootStore = rootStore;
        this.fetchMovies = this.fetchMovies.bind(this);
        this.setPrice = this.setPrice.bind(this);
    }


    @action
    async fetchMovies() {
        this.state = 'pending';
        this.movieList = [];
        try {
            const subjects = await Api.getMovie();
            //await之后更改状态
            runInAction(() => {
                this.state = 'Done';
                this.movieList = subjects;
            });
        } catch (e) {
            runInAction(() => {
                this.state = "error";
            });
        }
    }
}
复制代码

上面我们定义了2个状态,movieList:电影列表,state: 接口的请求状态,在其变量前面加上@observable 使其可观察,同时定义action,请求接口并改变初始状态,以上代码写法需要开启装饰器,(1)添加装饰器依赖

npm i babel-plugin-transform-decorators-legacy -D
复制代码

(2).babelrc文件添加配置

"plugins": ["transform-decorators-legacy"]
复制代码

Step 4: 创建视图以响应状态的变化

首先,在views目录下,新建movie文件来存放movie组件相关文件,在movie文件夹下创建index.jsx, 定义observer包裹React组件的高级组件

import React, {Component} from 'react';
import {observer} from "mobx-react";

@observer
export default class Movie extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>movie</div>
        )
    }
}
复制代码

Step 5: 全局注册并注入store实例

一个经常被问到的问题就是,如何不使用单例来组合多个 stores 。它们之间如何通信呢? 答案就是,创建一个 RootStore 来实例化所有 stores ,并共享引用; 示例: store/index.js

import {configure, observable, computed} from 'mobx';
import {movieStore} from './movieStore';
import {loginStore} from './loginStore';

configure({enforceActions: 'observed'});

export default class store {
    @observable movieStore;
    @observable loginStore;

    constructor() {
        this.movieStore = new movieStore(this);
        this.loginStore = new loginStore(this);
    }
}
复制代码

完成多个领域store的组合,使用

<Provider rootStore={new RootStore()}><App /></Provider>
复制代码

方式注入到组件库中。接下来就是在我们的视图组件中引入单个store,视角再次切换回到Movie组件,完善代码:

import React, {Component} from 'react';
import {inject, observer} from "mobx-react";
import { Table } from 'antd';

@inject((stores) => {
    return {
        movieStore: stores.store.movieStore
    }
})

@observer
export default class Movie extends Component {
    constructor(props) {
        super(props);
    }

    async componentDidMount(){
        const {movieList,fetchMovies} = this.props.movieStore;
        if (movieList.length > 0)
            return;
        await fetchMovies();
    }

    render() {
        const {state, movieList, setPrice, price} = this.props.movieStore;

        const columns = [{
            title: '名称',
            dataIndex: 'title',
            render: text => <a href="javascript:;">{text}</a>,
        }, {
            title: '豆瓣评分',
            dataIndex: 'rating',
        }, {
            title: '年份',
            dataIndex: 'year',
        }, {
            title: '描述',
            dataIndex: 'original_title'
        }];

        const data = movieList.map(item => ({
            id: item.id,
            key: item.id,
            title: item.title,
            rating: item.rating.average,
            year: item.year,
            original_title: item.original_title
        }));

        return (
            <div>
                <Table loading={state === 'pending'} columns={columns} dataSource={data} />
            </div>
        )
    }
}
复制代码

通过@inject,注入我们需要的store,注入之后我们可以在组件props中访问可观察属性和方法; 这里我使用antd UI库的table组件作为数据展示,有兴趣可去Ant Design官网

结语

以上是简单的mobx项目搭建,项目源代码请戳 react-mobx ,新手上路,以上都属于自己学习mobx的个人见解,如有理解错误之处,请各位大佬指出!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员代码面试指南:IT名企算法与数据结构题目最优解

程序员代码面试指南:IT名企算法与数据结构题目最优解

左程云 / 电子工业出版社 / 2015-9 / 79.00元

这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现。针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮助广大程序员的面试准备做到万无一失。“刷”完本书后,你就是“题王”!__eol__本书采用题目+解答的方式组织内容,并把面试题类型相近或者解法相近的题目尽量放在一起,读者在学习本书时很容易看出面试题解法之间的联......一起来看看 《程序员代码面试指南:IT名企算法与数据结构题目最优解》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试