当前位置: 首页 > news >正文

mobx学习笔记

mobx介绍

  • mobx是一个功能强大,上手容易的状态管理工具。
  • MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。
  • 利用getter和setter来收集组件的数据依赖关系,从而在数据发生变化的时候精确知道哪些组件需要重绘。

mobx和redux的区别

  • mobx更趋向于面向对象编程(OOP)
  • 对一份数据直接进行修改操作,不需要始终返回一个新的数据
  • 并非单一store,可以多store
  • redux默认以javascript原生对象形式存储数据,而mobx使用的是可观察对象

优缺点

优点
  • 学习成本小
  • 面向对象编程,对TS友好
缺点
  • mobx过于自由,提供的约束和模板代码很少,代码编写自由,如果不做一些约定,比较容易导致团队代码风格不同一
  • 相关的中间件很少,逻辑层业务整合是问题

mobx原则

MobX 支持单向数据流,也就是动作改变状态,而状态的改变会更新所有受影响的视图。
在这里插入图片描述
当状态改变时,所有衍生都会进行原子级的自动更新。因此永远不可能观察到中间值。
所有衍生默认都是同步更新。这意味着例如动作可以在改变状态之后直接可以安全地检查计算值。

mobx安装

yarn add -D mobx mobx-react

mobx的简单使用

import {observable,autorun} from 'mobx'

observable负责将数据转换为可观察的对象或者数组,
每次改数据时,就会在autorun的回调函数中触发,autorun相当于监听者。

对于普通数据的监听
// 对于普通数据的监听
let observableGender = observable.box('男');
// 监听变化(第一次必须执行,之后每次改变也会执行)
autorun(() => {console.log('observableNumber: ', observableGender.get());
});
// 设置
setTimeout(() => {observableGender.set('女');
}, 1000);

组件第一次渲染时,autorun会自动执行一次,如上例,以后每次相关可观察值改变,都会打印1次。

注意,在vconsole中可以看到mobx警告。
[MobX] Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed
在这里插入图片描述
mobx由于启用了严格模式,因此不允许在不使用action的情况下直接更改(观察到)值。异步的函数不能直接更改数据。
要更改可观察值,需要通过action触发。

对于对象的监听
// 对于对象的监听-------
let observableObj = observable.map({name: 'wuqing',age: 30,
});
autorun(() => {console.log('observableObj对象属性name:', observableObj.get('name'));
});
setTimeout(() => {// 只会打印1次,autorun只会监听与其相关的属性// observableObj.set('age', 100);observableObj.set('name', 'wuqing1');
}, 3000);

autorun只会监听与其相关的属性
对象监听另外一种写法:

let observableObj = observable({name: 'wuqing',age: 30,
});
autorun(() => {console.log('observableObj对象属性name:', observableObj.name);
});
setTimeout(() => {observableObj.name="wuqing1";
}, 3000);
为了代码风格统一,可以开启严格模式。

配置enforceActions: ‘always’,等于开启严格模式,必须用action触发数据更新。
若配置never,则不会启用。

import { observable, configure } from 'mobx';// 严格模式
configure({enforceActions: 'always',
});const store = observable({showMessage: false,name: '张伟',
});export default store;

配置严格模式后,若不通过action直接修改store数据,会报错 Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed.

严格模式默认应该是开启的。

可观察值只允许通过action方法改,不能直接改
import { observable, configure, action } from 'mobx';
// 严格模式
configure({enforceActions: 'always',
});
const store = observable({showMessage: false,name: '张伟',changeNameAction() {// 可观察值name的方法this.name = '刘德华';},},{changeNameAction: action, // 标记action是用于专门修改可观察值name的方法}
);
export default store;

上面换一种写法,用ES7注解器的写法是:
@observable和@action都是装饰器,通俗来说装饰器是将传入的值或者函数进行处理从而返回更加强大的值或者函数。

class Store {@observable name = '张伟';@observable showMessage = false;@action changeNameAction() {// 可观察值name的方法this.name = '刘德华' + Math.random();console.log('aaaa-->', this.name);}
}// 单例模式,无论谁导入,都是同一个对象
const store = new Store();export default store;

到这里,会发现react如果没有经过配置,直接使用decorators装饰器语法会报错,
在这里插入图片描述
Support for the experimental syntax ‘decorators’ isn’t currently enabled
因为react默认是不支持装饰器语法,需要做一些配置来启用装饰器语法。

step1:

在 tsconfig.json 中启用编译器选项 “experimentalDecorators”: true
vscode点击设置,输入搜索experimentalDecorators
在这里插入图片描述

step2:

安装支持修饰器所需依赖。

yarn add -D @babel/core @babel/plugin-proposal-decorators @babel/preset-env

创建.babelrc文件,配置

{"presets": ["@babel/preset-env"],"plugins": [["@babel/plugin-proposal-decorators",{"legacy": true}]]
}
step3:

安装依赖

yarn add -D customize-cra react-app-rewired

在项目根目录下创建 config-overrides.js 并写入以下内容,覆盖默认配置。

const path = require('path')
const { override, addDecoratorsLegacy } = require('customize-cra')function resolve(dir) {return path.join(__dirname, dir)
}const customize = () => (config, env) => {config.resolve.alias['@'] = resolve('src')if (env === 'production') {config.externals = {'react': 'React','react-dom': 'ReactDOM'}}return config
};
module.exports = override(addDecoratorsLegacy(), customize())
step4:

修改package.json文件中 scripts 脚本。

"scripts": {"start": "react-app-rewired start","build": "react-app-rewired build","test": "react-app-rewired test","eject": "react-scripts eject"}

上面4个步骤配置完成后,如果mobx修饰器还是不起作用,就可能是mobx版本有问题,执行step5。

step5:

执行下面命令

yarn add -D mobx@5 mobx-react@5

执行到step5,就能成功使用mobx修饰器了。

注意,如果报错
Parsing error: Cannot use the decorators and decorators-legacy plugin together
在这里插入图片描述
可以创建.eslintrc.js文件,配置即可解决eslint报错问题

parserOptions: {parser: 'babel-eslint',ecmaFeatures: {// 支持装饰器legacyDecorators: true,},},

在这里插入图片描述

mobx核心API介绍

observable: observable是将类属性等进行标记,实现对其的观察。
actions:动作,通过action改变state。action函数是对传入的function进行一次包装,使得function中的observable对象的变化能够被观察到,从而触发相应的衍生。
autoRun:当你想创建一个响应式函数,但是该函数永远没有观察者,此时使用autorun。这通常是当你需要从反应式代码桥接到命令式代码的情况,例如打印日志、持久化或者更新UI的代码。
当使用 autorun 时,所提供的函数总是立即被触发一次,然后每次它的依赖关系改变时会再次被触发。
相比之下,computed(function) 创建的函数只有当它有自己的观察者时才会重新计算,否则它的值会被认为是不相关的。 经验法则:如果你有一个函数应该自动运行,但不会产生一个新的值,请使用autorun。 其余情况都应该使用 computed。
装饰器
runInAction:工具函数,是创建异步action的一种方式。
action只会对当前包装/装饰的函数做出反应,而不会对当前运行函数所调用的函数(不包含在当前函数之内)作出反应!这意味着如果 action 中存在 setTimeout、promise 的 then 或 async 语句,并且在回调函数中某些状态改变了,那么这些回调函数也应该包装在 action 中。
@observable
定义 state
@computed
可以定义在相关数据发生变化时自动更新的值,像这样的计算可以类似于 MS Excel 这样电子表格程序中的公式。每当只有在需要它们的时候,它们才会自动更新。
@action
定义操作 state 的方法。
@observer
用来将 React 组件转变成响应式组件。observer 是由单独的 mobx-react 包提供的。
@inject
将组件连接到提供的 stores。
mobx-react 包还提供了 Provider 组件,它使用了 React 的上下文(context)机制,可以用来向下传递 stores。 要连接到这些 stores,需要传递一个 stores 名称的列表给 inject,这使得 stores 可以作为组件的 props 使用。

使用

新建store.js,封装Store Class专门用于状态管理,再export Store的实例对象store。

import { action, configure, observable, runInAction } from 'mobx';
// 严格模式
configure({enforceActions: 'always',
});
class Store {@observable name = '张伟';@observable showMessage = false;@observable messageList = [];@action changeNameAction() {// 可观察值name的方法this.name = '刘德华' + Math.random();}@action async getMessageList() {const datas = await getMessageListApi();// 异步runInAction(()=>{this.messageList=datas})}
}
// 单例模式,无论谁导入,都是同一个对象
const store = new Store();export default store;function getMessageListApi() {return new Promise((resolve) => {return setTimeout(() => {const list = [];for (let i = 0; i < 5; i++) {list.push(`MSG-${Math.random()}`);}resolve(list);}, 1500);});
}

从mobx-react中引入Provider,全局注册并注入store实例,内部组件就能使用到store中的state

import { Provider } from 'mobx-react';
import store from './mobx-demo/Store/store-1';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(// store属性名自命名,为了区别,写了一个demo名<Provider demoStore={store}><App /></Provider>
);

内部组件需要使用state时,先要用@inject装饰器注入store,再用@observer将组件标记为 observer,当组件中使用到的store state发生变化时,组件会自动响应更新。

@inject("demoStore") // 通过inject修饰器注入store
@observer
export default class App extends Component {componentDidMount() {console.log('name-->', this.props.demoStore.name);}render() {return <RouterProvider router={routes}></RouterProvider>;}
}

相关文章:

mobx学习笔记

mobx介绍 mobx是一个功能强大&#xff0c;上手容易的状态管理工具。MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。利用getter和setter来收集组件的数据依赖关系&#xff0c;从而在数据发生变化的时候精确知道哪些组件需要重绘。 mobx和redux的区别 mobx更…...

深入理解 Cowboy WebSocket:使用 Erlang/OTP 构建高效的即时通讯(IM)应用

深入理解 Cowboy WebSocket&#xff1a;使用 Erlang/OTP 构建高效的即时通讯(IM)应用 引言 实时通信技术在现代 Web 应用中扮演着核心角色&#xff0c;而 WebSocket 作为其中的关键技术&#xff0c;已成为即时通讯(IM)系统不可或缺的一部分。Cowboy&#xff0c;这个基于 Erla…...

算法的几种常见形式

算法&#xff08;Algorithm&#xff09; 算法&#xff08;Algorithm&#xff09;是指解决问题或完成任务的一系列明确的步骤或规则。在计算机科学中&#xff0c;算法是程序的核心部分&#xff0c;它定义了如何执行特定的任务或解决特定的问题。算法可以用多种方式来表示和实现…...

SpringBoot新手快速入门系列教程二:MySql5.7.44的免安装版本下载和配置,以及简单的Mysql生存指令指南。

我的教程都是亲自测试可行才发布的&#xff0c;如果有任何问题欢迎留言或者来群里我每天都会解答。 我们要如何选择MySql 目前主流的Mysql有5.0、8.0、9.0 主要区别 MySQL 5.0 发布年份&#xff1a;2005年特性&#xff1a; 基础事务支持存储过程、触发器、视图基础存储引擎…...

Elasticsearch 更新指定字段

Elasticsearch 更新指定字段 准备条件查询数据更新指定字段更新子级字段 准备条件 以下查询操作都基于索引crm_clue来操作&#xff0c;索引已经建过了&#xff0c;本文主要讲Elasticsearch更新指定字段语句&#xff0c;下面开始写更新语句执行更新啦&#xff01; 查询数据 查…...

Koa.js、Egg.js与Express.js:探析三大Node.js框架的异同

在Node.js的世界里&#xff0c;选择合适的框架对于构建高效、可维护的后端服务至关重要。Express.js、Koa.js 和 Egg.js 是三个备受欢迎的框架&#xff0c;它们各有特色&#xff0c;适用于不同的开发场景。本文旨在深入探讨这三个框架的区别&#xff0c;并通过代码示例帮助开发…...

【MYSQL】如何解决 bin log 与 redo log 的一致性问题

该问题问的其实就是redo log 的两阶段提交 为什么说redo log 具有崩溃恢复的能力 MySQL Server 层拥有的 bin log 只能用于归档&#xff0c;不足以实现崩溃恢复&#xff08;crash-safe&#xff09;&#xff0c;需要借助 InnoDB 引擎的 redo log 才能拥有崩溃恢复的能力。所谓崩…...

翻译语音识别在线的软件,分享4款实用的软件!

在全球化日益加速的今天&#xff0c;语言沟通已成为人们生活中不可或缺的一部分。无论是商务洽谈、学术交流还是日常交流&#xff0c;翻译语音识别技术都扮演着举足轻重的角色。今天&#xff0c;我们就来揭秘一下&#xff0c;那些能让你在语言沟通中如虎添翼的翻译语音识别软件…...

Qt 的Q_PROPERTY关键字

Qt 的Q_PROPERTY关键字 1. Q_PROPERTY 的由来2. 实现原理3. Q_PROPERTY 的特点4. Q_PROPERTY 的属性5. 应用说明示例代码示例代码连接信号和槽的多种方式处理信号和槽的注意事项 QT的元对象系统1. 元对象系统的由来2. 实现原理3. 元对象系统的特点4. 元对象系统的属性5. 应用说…...

github 下载提速的几种方法

1. 代理下载&#xff08;无需注册&#xff09; //toolwa.com/github/ //d.serctl.com/2. 转入 Gitee 加速 将项目镜像到 Gitee 中下载加速 3. 使用 Watt Toolkit 加速 Watt Toolkit //steampp.net/选择合适的版本下载 选择 github&#xff0c;一键加速 4.CDN 加速 (修改…...

【Oracle】实验三 Oracle数据库的创建和管理

【实验目的】 掌握Oracle数据库的创建方法使用DBCA创建数据库在数据库中装入SCOTT用户及其表 【实验内容】 使用DBCA创建数据库&#xff0c;名为MYDB&#xff0c;找到其初始化文件(文本型和服务器型文件都要找到)&#xff0c;查看各类默认位置并记录下来(包括物理文件所在目…...

Linux rpm和ssh损坏修复

背景介绍 我遇到的问题可能和你的不一样。但是如果遇到错误一样也可以按此方案尝试修复。 我是想在Linux上安装Oracle&#xff0c;因为必须在离线环境下安装。就在网上搜一篇文章linux离线安装oracle&#xff0c;然后安装教程走&#xff0c;进行到安装oracle依赖包的时候执行了…...

仕考网:公务员考试面试时间一般多长?

公务员考试主要分为笔试与面试两个阶段&#xff0c;其中面试是笔试通过的下一关&#xff0c;面试的具体安排通常由相关考试机构或招录单位负责发布并通知考生。 公务员面试的持续时间一般在30分钟至1小时之间&#xff0c;具体时长可能因地区和招录单位的不同而有所变化。常见的…...

C语言作业5(学生管理系统C语言)

成学生管理系统 1> 使用菜单完成 2> 有学生的信息录入功能&#xff1a;输入学生个数&#xff0c;并将学生的姓名、分数录入 3> 查看学生信息&#xff1a;输出所有学生姓名以及对应的分数 4> 求出学习最好的学生信息&#xff1a;求最大值 5> 按姓名将所有学…...

OS Copilot:新手测评体验

文章目录 前言一、OS Copilot&#xff08;阿里云操作系统智能助手&#xff09;简介二、测评体验总结OS Copilot 产品体验评测OS Copilot 产品功能反馈 前言 本文简单分享一下自己使用OS Copilot测评体验。 一、OS Copilot&#xff08;阿里云操作系统智能助手&#xff09;简介 …...

PS 2024【最新】中文白嫖版!,安装教程,图文步骤

文章目录 软件介绍软件下载安装步骤 软件介绍 Photoshop&#xff0c;简称“PS” Adobe Photoshop&#xff0c;简称“PS”&#xff0c;是由Adobe Systems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具&#xff0c;可以有效地…...

bind方法的使用

在JavaScript或TypeScript中&#xff0c;this.data.setEventListener(this.onAddEvent.bind(this)); 和 this.data.setEventListener(this.onAddEvent); 之间的主要区别在于this关键字的绑定方式。 不使用.bind(this) 当你直接传递函数引用 this.onAddEvent给 setEventListene…...

MySQL数据库基本操作-DDL和DML

1. DDL解释 DDL(Data Definition Language)&#xff0c;数据定义语言&#xff0c;该语言部分包括以下内容&#xff1a; 对数据库的常用操作对表结构的常用操作修改表结构 2. 对数据库的常用操作 功能SQL查看所有的数据库show databases&#xff1b;查看有印象的数据库show d…...

iOS 应用内存超过多少会收到系统内存警告 ?

iOS 应用内存超过多少会收到系统内存警告 &#xff1f; 在 iOS 应用中&#xff0c;系统内存警告的触发是由 iOS 操作系统动态决定的&#xff0c;并不是一个固定的阈值。系统会根据当前设备的可用内存、正在运行的其他应用程序的内存需求以及当前应用程序的内存占用情况来判断是…...

【分布式系统】Filebeat+Kafka+ELK 的服务部署

目录 一.实验准备 二.配置部署 Filebeat 三.配置Logstash 四.验证 一.实验准备 结合之前的博客中的实验 主机名ip地址主要软件es01192.168.80.101ElasticSearches02192.168.80.102ElasticSearches03192.168.80.103ElasticSearch、Kibananginx01192.168.80.104nginx、Logs…...

Qt Qwt 图表库详解及使用

文章目录 Qt Qwt 图表库详解及使用一、Qwt 概述二、安装 Qwt1. 下载和编译 Qwt2. 在项目中使用 Qwt三、Qwt 的基本使用1. 创建一个简单的折线图2. 添加图例和自定义样式四、Qwt 的交互功能1. 启用缩放和平移2. 启用数据点选择五、Qwt 的高级特性1. 实时数据更新2. 多轴绘图六、…...

基于B站视频评论的文本分析,采用包括文本聚类分析、LDA主题分析、网络语义分析

研究主题 本研究旨在通过对B站视频评论数据进行文本分析&#xff0c;揭示用户评论的主题、情感倾向和语义结构&#xff0c;助力商业决策。主要技术手段包括Python爬虫、LDA主题分析、聚类分析和语义网络分析。首先&#xff0c;利用Python爬虫采集大量评论数据并进行预处理。运…...

【Qt】xml Dom复制

1. 功能 将A.xml文件中的copyNode节点全部复制到B.xml中的testRoot节点。 2. 代码 #include <QDomDocument> #include <QFile> #include <QIODevice> #include <QtXml>void copyNodeXml() {// 源文件DOMQDomDocument ADoc;// 加载源文件QFile fileA(…...

MySQL联合索引最左匹配原则

MySQL中的联合索引(也叫组合索引)遵循最左匹配原则&#xff0c;即在创建联合索引时&#xff0c;查询条件必须从索引的最左边开始&#xff0c;否则索引不会被使用。在联合索引的情况下&#xff0c;数据是按照索引第一列排序&#xff0c;第一列数据相同时才会按照第二列排序。 例…...

2024最新最全面的软件测试自动化面试题(含答案)

1.如何把自动化测试在公司中实施并推广起来的&#xff1f; 选择长期的有稳定模块的项目 项目组调研选择自动化工具并开会演示demo案例&#xff0c;我们主要是演示selenium和robot framework两种。 搭建自动化测试框架&#xff0c;在项目中逐步开展自动化。 把该项目的自动化…...

Linux磁盘-MBRGPT

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 Linux磁盘涉及到的命令不是很多&#xff0c;但是在实际运维中的作用却很大&#xff0c;因为Linux系统及业务都会承载到硬盘上…...

kind kubernetes(k8s虚拟环境)使用本地docker的镜像

kubernetes中&#xff0c;虽然下载镜像使用docker&#xff0c;但是存储在docker image里的镜像是不能被k8s直接使用的&#xff0c;但是kind不同&#xff0c;可以使用下面的方法&#xff0c;让kind kubernetes环境使用docker image里的镜像。 kind – Quick Start 例如&#x…...

kafka发送消息流程

配置props.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, RoundRobinPartitioner.class); public Map<String,Object> producerConfigs(){Map<String,Object> props new HashMap<>();props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,bootstrapServers…...

使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-敌人生成器(八)

文章目录 开发思路敌人生成器代码分析属性配置 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击&#xff08;一&#xff09; 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-激光组件&#xff08;二&#xff09; 使用Godot4组件制作竖版太空射击游戏_2D卷轴飞机射击-飞…...

Allegro中show elements不弹窗问题

今天allegro用的好好的&#xff0c;刚刚还可以正常使用show elements进行对象的详细信息查看的&#xff0c;突然就不好使了&#xff0c;具体表现为不弹窗。 找了好久找到一个类似问题的&#xff0c;具体的解决方法是&#xff1a; D:\Allegro\Cadence\SPB_Data\pcbenv在allegro的…...

简洁汽车配件网站模板/百度知道网页版登录入口

什么是冒泡排序&#xff1f; 是通过挨个的比较&#xff0c;将最大&#xff08;或最小&#xff09;数字层层交换至所有数据的开头&#xff0c;每冒一次&#xff0c;数据头部往后移一位&#xff0c;经过N次冒泡之后&#xff0c;得到最终排序&#xff01;&#xff01;&#xff01…...

企业网站源码哪个好/nba最新交易

2019独角兽企业重金招聘Python工程师标准>>> 在遍历数组的时候swift的forin给我们提供了更方便的模式,直接上代码解释 let btnName ["aaa", "bbb", "ccc", "ddd", "eee"] for (index,name) in btnName.enumerat…...

他达拉非片正确服用方法/搜索引擎优化包括哪些内容

tooltip样式主要通过formatter设置&#xff0c;官网明确指出支持字符串模板和回调函数两种形式。 1.字符串模板 举例&#xff1a; tooltip: {trigger: item,formatter: {a} <br/>{b} : {c} ({d}%),confine: true},结果如下图所示&#xff1a; 2.回调函数 回调函数 支…...

flash网站制作教程/互联网广告平台有哪些

目录第1章 制作纸质加密工具1.1 密码学是什么1.2 代码与加密法1.3 制作纸质加密轮盘1.4 虚拟加密轮盘1.5 如何使用加密轮盘加密1.6 如何使用加密轮盘解密1.7 另一个加密法工具&#xff1a;St.Cyr滑条1.8 A组练习1.9 不用纸质工具做加密1.10 B组练习1.11 双重强度加密1.12 通过计…...

湖南建设人力资源网和报考平台/齐三seo顾问

01 开启多条线程&#xff0c;每条线程都只下载文件的一部分&#xff08;通过设置请求头中的Range来实现&#xff09; 02 创建一个和需要下载文件大小一致的文件&#xff0c;判断当前是那个线程&#xff0c;根据当前的线程来判断下载的数据应该写入到文件中的哪个位置。&#xf…...

专业网站维护/服务营销的七个要素

点击上方“Java基基”&#xff0c;选择“设为星标”做积极的人&#xff0c;而不是积极废人&#xff01;源码精品专栏 原创 | Java 2020 超神之路&#xff0c;很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库…...