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

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

内容简介: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的个人见解,如有理解错误之处,请各位大佬指出!


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

查看所有标签

猜你喜欢:

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

精通Windows应用开发

精通Windows应用开发

[美] Jesse Liberty Philip Japikse Jon Galloway / 苏宝龙 / 人民邮电出版社 / 59.00元

Windows 8.1的出现不仅提供了跨设备的用户体验,也提供了跨设备的开发体验。本书着眼于实际项目中所需要的特性,以及现有C#编程知识的运用,对如何最大限度地利用Metro、WinRT和Windows 8进行了讲解,内容详尽,注重理论学习与实践开发的配合。 Windows 8.1和WinRT的作用及其特殊性 如何使用先进特性创建具有沉浸感和吸引力的Windows 8.1应用 如......一起来看看 《精通Windows应用开发》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具