React:状态管理Mobx

一、介绍

MobX 是一个身经百战的库,它通过运用透明的函数式响应编程(Transparent Functional Reactive Programming,TFRP)使状态管理变得简单和可扩展。

简单直接
编写无模板的极简代码来精准描述出你的意图。要更新一个记录字段?使用熟悉的 JavaScript 赋值就行。要在异步进程中更新数据?不需要特殊的工具,响应性系统会侦测到你所有的变更并把它们传送到其用武之地。

轻松实现最优渲染
所有对数据的变更和使用都会在运行时被追踪到,并构成一个截取所有状态和输出之间关系的依赖树。这样保证了那些依赖于状态的计算只有在真正需要时才会运行,就像 React 组件一样。无需使用记忆化或选择器之类容易出错的次优技巧来对组件进行手动优化。

架构自由
MobX 不会用它自己的规则来限制你,它可以让你在任意 UI 框架之外管理你的应用状态。这样会使你的代码低耦合、可移植和最重要的——容易测试。

二、环境搭建
  1. 使用 create-react-app 脚手架搭建的 react项目
$ npx create-react-app mobx-react-app
  1. 安装 Mobx 、中间件 mobx-react-lite(仅支持函数组件)
$ npm i mobx mobx-react-lite
  1. mobx-react-appx工程 src 目录下新建 store 文件夹,后续操作在该文件夹内操作
二、使用
1.初始化mobx
  • 定义数据状态 state
  • 数据响应式处理
  • 定义 action 函数(修改数据)
  • 实例化并导出实例
// src/store/count.js mobx store实例
import { makeAutoObservable } from "mobx";

class CountStore {
    // 1. 定义数据状态
    count = 0;

    constructor () {
        // 2. 数据响应式处理
        makeAutoObservable(this);
    }

    addCount = () => {
        // 3. 定义 action 函数
        this.count ++;
    }
}

// 实例化
const countStore = new CountStore();
export {countStore};


2. 连接react
  • 导入 store实例
  • 使用 store 数据
  • 修改store数据
  • 使用中间件 方法 响应化数据
// App.js
import React from "react";
// 1.导入 store 实例
import {countStore} from './store/count';
// 4. 导入 中间件的 方法 响应化视图
import {observer} from 'mobx-react-lite';

function App() {
  return (
    <div>
      app
      {/**2.使用store数据 */}
      {countStore.count}
      {/**3.通过store实例方法 修改数据 */}
      <button onClick={countStore.addCount}>add</button>
    </div>
  )
}

// observer 包裹App,实现视图响应式
export default observer(App);

3.computed计算属性
  • 声明一个数据
  • 定义 get 计算属性
  • 在 makeAutoObservable 方法中标记
// src/store/count
import { makeAutoObservable, computed } from "mobx";

class CountStore {
    list = [1,2,3,4]

    constructor () {
        // 数据响应式处理
        makeAutoObservable(this, {
            filterlist:computed // 计算属性标记,为何这里不标记,也可以?????
        });
    }

    // 定义 get计算属性
    get filterlist() {
        return this.list.filter(n => n > 2);
    }

    addList = () => {
        this.list.push(6,7,8)
    }
}

// 实例化
const countStore = new CountStore();
export {countStore};

问题解答:

  1. 为什么不设置 filterlist:computed 属性,也能 响应式更新?
    因为 makeAutoObservable 会将所有的 getters 被自动声明为 computed,相同功能的还有 observableextendObservable
// App.js
import React from "react";
// 1.导入 store 实例
import {countStore} from './store/count';
// 4. 导入 中间件的 方法 响应化视图
import {observer} from 'mobx-react-lite';

function App() {
  return (
    <div>
      {countStore.list.join('-')}
      <button onClick={countStore.addList}>push</button>
    </div>
  )
}

// observer 包裹App,实现视图响应式
export default observer(App);

三、Mobx模块化

在这里插入图片描述

操作步骤
  1. 拆分count、list模块,每个模块定义自己的 state/action
  2. 在 store/index.js 中导入拆分后的模块,进行模块组合
  3. 使用 React 的 useContext机制导出 useStore 方法,供业务组件统一使用
// store/list.Store.js
// 子模块1 listStore
import { makeAutoObservable } from "mobx";

class ListStore {
    list = ['李白','杜甫'];
    constructor () {
        makeAutoObservable(this)
    }

    addList = () => {
        this.list.push('白居易')
    }
}

export {ListStore}
// store/count.Store.js
// 子模块2: countStore

import { makeAutoObservable, computed } from "mobx";

class CountStore {
    // 1. 定义数据状态
    count = 0;
    list = [1,2,3,4]

    constructor () {
        // 2. 数据响应式处理
        makeAutoObservable(this, {
            // filterlist:computed // 计算属性标记
        });
    }

    addCount = () => {
        // 3. 定义 action 函数
        this.count ++;
    }

    // 定义 get计算属性
    get filterlist() {
        return this.list.filter(n => n > 2);
    }

    addList = () => {
        this.list.push(6,7,8)
    }
}

export {CountStore};
// store/index.js
// 组合子模块
import { createContext, useContext } from 'react';
import {ListStore} from './list.Store';
import { CountStore } from './count.Store';

class RootStore {
    constructor () {
        // 实例化子模块
        // 后续 根store 有两个属性,分别是 listStore 和 countStore
        this.listStore = new ListStore();
        this.countStore = new CountStore();
    }
}

// 实例化操作
const rootStore = new RootStore();
// 通过 createContext机制,完成统一封装
// 查找机制:useContext 优先从 Provider value找,如果找不到,就会找 createContext 传递过来的默认参数
const context = createContext(rootStore);

const useStore = () => useContext(context);

export {useStore}
// App.js
import React from "react";
import {observer} from 'mobx-react-lite';


import { useStore } from "./store";

function App() {
  const {countStore} = useStore();

  return (
    <div>
      {countStore.count}
      <button onClick={countStore.addCount}>add</button>
    </div>
  )
}

// observer 包裹App,实现视图响应式
export default observer(App);

```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端卡卡西呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值