在react中使用Mobx

全局状态管理 Mobx。

设计理念:任何从应用派生出的状态,都应被自动(获得更新),包括UI、序列化数据、服务通信等。

Mobx使用了class语法以及装饰器,参考:ES6 class语法、装饰器

create-react-app配置使用mobx

由于mobx使用了装饰器语法,所以需要配置在react中使用装饰器@**

首先,安装mobx/mobx-react

npm install mobx mobx-react

通过增加babelbabel-preset-mobx,预设支持。

npm install babel-preset-mobox --save-dev

最后配置config-overrides.js,

const {
    override,
    addWebpackAlias,
    addBabelPresets,
  } = require("customize-cra"); 
  const path = require("path");

module.exports = override(
	// 预设支持 mobx 装饰器语法
    ...addBabelPresets(["mobx"]),
    addWebpackAlias({
        ["@Component"]:path.resolve(__dirname,'src/example')
    })
);

mobx/mobx-react使用

mobx 通过

  1. observable观测属性,
  2. computed计算属性,通过已观测属性计算出新属性;

用户实体类对象声明;用户列表实体对象声明。

/**
 * 用户属性监听
 */
import {observable,computed} from 'mobx';

// 单用户实体信息
class UserInfo{
    id = Date.now();
    @observable name = "";
    @observable age = "";
    @observable online = false;
    constructor(name,age,online){
        this.name = name;
        this.age = age;
        this.online = online
    }
}
// 多用户列表
class UserList{
    constructor(list){
        this.userList = list;
    }
    @observable userList = [];
    @computed get onlineNum(){
        // 统计用户列表中在线用户
        return this.userList.filter(user=>user.online).length;
    }
}

export {UserInfo,UserList}

react中使用mobx,通过mobx-react可关联观测组件,所有依赖观测属性的组件,在属性变化时触发组件更新。

/**
 * Mobx.js 用于全局状态管理
 * Mobx-react 将mobx全局数据状态绑定到react
 */
import React from 'react';
import {observer} from 'mobx-react';
import {Form,Checkbox} from 'antd';
import {UserInfo,UserList} from './UserInfo';

@observer
class ListUser extends React.Component{
    constructor(props){
        super(props);
        this.state = {}
    } 
    render(){
        return (<div>
            <p>Online Total:{this.props.userList.onlineNum}</p>
            <ul>
                {this.props.userList.userList.map(user=><UserItem key={user.id} user={user} />)}
            </ul>
        </div>)
    }
}
const formLayout = {
    labelCol:{
        span:3
    },
    wrapperCol:{
        span:4
    }
}
const UserItem = observer(({user})=><li>
    <Form layout="horizontal" {...formLayout} initialValues={{
        'online':user.online
    }}>
        <Form.Item label="姓名" name="name">
            <span>{user.name}</span>
        </Form.Item>
        <Form.Item label="年龄" name="age">
            <span>{user.age}</span>
        </Form.Item>
        <Form.Item label="是否在线" name="online" valuePropName="checked">
            <Checkbox onChange={e=>user.online = e.target.checked} />
        </Form.Item>
    </Form>
</li>);

测试组件ListUser,传入props属性userList

// 测试数据
let user1 = new UserInfo("admin",32,true);
let user2 = new UserInfo("test",12,false);
let user3 = new UserInfo("小明",22,false);
let list = new UserList([user1,user2,user3]);
export default function MobxDemo(){
    return (<ListUser userList = {list} />)
};

测试截图:
在这里插入图片描述

核心API

常用的用于状态属性管理的API说明。

observable ,创建可观测属性,包括基本数据类型/引用类型、类实例、数组和映射。

  1. observable(value)方法创建;
    // 直接使用observable 方法,定义观测数据对象
    let store = observable({
        name:"hello"
    });
    // 定义观测组件
    const Test = observer((props)=><>
        <span>{props.obj.name}</span>
        <button onClick={e=>props.obj.name="world"}>更新</button>
    </>);
    // 组件使用,传入数据
    <Test obj = {store} />
    
  2. @observable classProperty = value 观测class类属性

装饰器相关,调节属性的可观察性。控制特定属性的转换规则。

  1. computed 创建一个计算的衍生属性。
  2. action 创建一个动作,用于更新状态;可以用于处理异步动作。
  3. decorate 无法使用装饰器@,可应用属性观测的方法
    // 手动定义可观测对象的属性的观测方式
    decorate(UserList,{
        userList:observable,
        onlineNum:computed
    });
    
  4. autorun(fn) 创建一个响应式函数,初始立即触发一次啊,然后依赖关系改变时再次被触发。执行后返回一个清理autorun 的函数
  5. when(()=>Boolean,effect?:()=>void,options) 观察并运行给定的语句,知道返回true。一旦返回true,执行effect

比较redux

对比redux,个人方面使用更顺手,同Vue.js绑定原理一样,通过收集依赖组件,对其进行更新:

  1. 使用装饰器@**更简洁的属性、组件观测。
  2. 使用class语法声明对象实体,观测属性声明。
  3. 属性更新的方式,直接通过元素的监听事件更新或者更新传入观测组建的对象
    // 动态更新 传入ListUser组件的属性对象
    setTimeout(()=>{
        list.userList.push(new UserInfo("小李",20,false));
    },3000);
    export default function MobxDemo(){
        return (<ListUser userList = {list} />)
    };
    

局限:

  1. Observable数组并非真正的数组,在传递给第三方库之前,通过.slice()操作。
  2. 对已存在的observable对象动态添加属性不会被捕获,可通过映射代替或者使用工具函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

heroboyluck

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

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

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

打赏作者

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

抵扣说明:

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

余额充值