【MobX】391- MobX 入门教程(下)
三、MobX 常用 API 介绍
3. 修改可观察数据
在上一部分内容中,我们了解到,对可观察的数据做出反应的时候,需要我们手动修改可观察数据的值。这种修改是通过直接向变量赋值来实现的,虽然简单易懂,但是这样会带来一个较为严重的副作用,就是每次的修改都会触发 autorun 或者 reaction 运行一次。多数情况下,这种高频的触发是完全没有必要的。
比如用户对视图的一次点击操作需要很多修改 N 个状态变量,但是视图的更新只需要一次就够了。
为了优化这个问题, MobX 引入了 action 。
3.1 (@)action
action 是修改任何状态的行为,使用 action 的好处是能将多次修改可观察状态合并成一次,从而减少触发 autorun 或者 reaction 的次数。
可以理解成批量操作,即一次动作中包含多次修改可观察状态,此时只会在动作结束后,做一次性重新计算和反应。
action 也有两种使用方法,这里以 decorate 方式来介绍。
import { observable, computed, reaction, action} from 'mobx'
class Store {
@observable string = 'leo';
@observable number = 123;
@action bar(){
this.string = 'pingan'
this.number = 100
}
}
let store = new Store()
reaction(() => [store.string, store.number], arr => {
console.log(arr)
})
store.bar() // ["pingan", 100]
当我们连续去修改 store.string 和 store.number 两个变量后,再运行 store.bar() 会发现,控制台值输出一次 ["pingan", 100] ,这就说明 reaction 只被执行一次。
知识点:action.bound
另外 action 还有一种特殊使用方法:action.bound,常常用来作为一个 callback 的方法参数,并且执行效果也是一样:
import { observable, computed, reaction, action} from 'mobx'
class Store {
@observable string = 'leo';
@observable number = 123;
@action.bound bar(){
this.string = 'pingan'
this.number = 100
}
}
let store = new Store()
reaction(() => [store.string, store.number], arr => {
console.log(arr)
})
let bar = store.bar;
function foo(fun){
fun()
}
foo(bar) //["pingan", 100]
知识点:runInAction(name?, thunk)
runInAction 是个简单的工具函数,它接收代码块并在(异步的)动作中执行。这对于即时创建和执行动作非常有用,例如在异步过程中。runInAction(f) 是 action(f)() 的语法糖。
import { observable, computed, reaction, action} from 'mobx'
class Store {
@observable string = 'leo';
@observable number = 123;
@action.bound bar(){
this.string = 'pingan'
this.number = 100
}
}
let store = new Store()
reaction(() => [store.string, store.number], arr => {
console.log(arr)
})
runInAction(() => {
store.string = 'pingan'
store.number = 100
})//["pingan", 100]
四、 Mobx-React 简单实例
这里以简单计数器为例,实现点击按钮,数值累加的简单操作,如图:
在这个案例中,我们引用 mobx-react 库来实现,很明显可以看出 mobx-react 是作为 mobx 和 react 之前的桥梁。
它将 react 组件转化为对可观察数据的反应,也就是将组件的 render 方法包装成 autorun 方法,使得状态变化时能自动重新渲染。
详细可以查看:https://www.npmjs.com/package/mobx-react 。
接下来开始我们的案例:
1. 安装依赖和配置webpack
由于配置和前面第二节介绍差不多,所以这里会以第二节的配置为基础,添加配置。
首先安装 mobx-react 依赖:
cnpm i mobx-react -D
修改webpack.config.js,在 presets 配置中添加 react 进来:
// ... 省略其他
- entry: path.resolve(__dirname, 'src/index.js'),
+ entry: path.resolve(__dirname, 'src/index.jsx'),
module: {
rules: [{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
- presets: ['env'],
+ presets: ['env', 'react'],
plugins: ['transform-decorators-legacy', 'transform-class-properties']
}
}
}]
},
2. 初始化 React 项目
这里初始化一下我们本次项目的简单骨架:
// index.jsx
import { observable, action} from 'mobx';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {observer, PropTypes as observablePropTypes} from 'mobx-react'
class Store {
}
const store = new Store();
class Bar extends Component{
}
class Foo extends Component{
}
ReactDOM.render(<Foo />, document.querySelector("#root"))
这些组件对应到我们最后页面效果如图:
2. 实现 Store 类
Store 类用于存储数据。
class Store {
@observable cache = { queue: [] }
@action.bound refresh(){
this.cache.queue.push(1)
}
}
3. 实现 Bar 和 Foo 组件
实现代码如下:
@observer
class Bar extends Component{
static propTypes = {
queue: observablePropTypes.observableArray
}
render(){
const queue = this.props.queue;
return <span>{queue.length}</span>
}
}
class Foo extends Component{
static propTypes = {
cache: observablePropTypes.observableObject
}
render(){
const cache = this.props.cache;
return <div>
<button onClick={this.props.refresh}>点击 + 1</button>
当前数值:<Bar queue={cache.queue} />
</div>
}
}
这里需要注意:
可观察数据类型中的数组,实际上并不是数组类型,这里需要用
observablePropTypes.observableArray去声明它的类型,对象也是一样。@observer在需要根据数据变换,而改变UI的组件去引用,另外建议有使用到相关数据的类都引用。事实上,我们只需要记住
observer方法,将所有React组件用observer修饰,就是react-mobx的用法。
4. 使用 Foo 组件
最后我们使用 Foo 组件,需要给它传递两个参数,这样 Bar 组件才能拿到并使用:
ReactDOM.render(
<Foo cache={store.cache}
refresh={store.refresh}
/>,
document.querySelector("#root")
)
结尾
本文参考:
- 《MobX 官方文档》
- 茵风泳月《MobX 入门基础教程》
【MobX】391- MobX 入门教程(下)的更多相关文章
- 【MobX】390- MobX 入门教程(上)
点击上方"前端自习课"关注,学习起来~ 本文考虑到篇幅问题,将<MobX 入门教程>分成上.下两篇文章,方便阅读.分配安排: 一.MobX 介绍 首先看下官网介绍: ★ ...
- django入门教程(下)
在两篇文章帮你入门Django(上)一文中,我们已经做了一个简单的小网站,实现了保存用户数据到数据库,以及从后台数据库读取数据显示到网页上这两个功能. 看上去没有什么问题了,不过我们可以让它变得更加完 ...
- jenkins 入门教程(下)
接上回继续学习jenkins,这次主要来看一些疑难杂症: 一.yum install安装方式 除了直接java -jar jenkins.war方式,还可以用yum安装,这种方式下提供了更多的可配置选 ...
- Odoo进销存(采购、销售、仓库)入门教程 - 下
转帖地址:http://blog.csdn.net/wangnan537/article/details/46475105 2. 进销存实务 2.1 销售产品 李逍遥接到客户苏州美尚邻里超市购买10只 ...
- Spring Boot入门教程1、使用Spring Boot构建第一个Web应用程序
一.前言 什么是Spring Boot?Spring Boot就是一个让你使用Spring构建应用时减少配置的一个框架.约定优于配置,一定程度上提高了开发效率.https://zhuanlan.zhi ...
- Spring Boot入门教程2-1、使用Spring Boot+MyBatis访问数据库(CURD)注解版
一.前言 什么是MyBatis?MyBatis是目前Java平台最为流行的ORM框架https://baike.baidu.com/item/MyBatis/2824918 本篇开发环境1.操作系统: ...
- Spring Cloud 入门教程(四): 分布式环境下自动发现配置服务
前一章, 我们的Hello world应用服务,通过配置服务器Config Server获取到了我们配置的hello信息“hello world”. 但自己的配置文件中必须配置config serve ...
- Unity入门教程(下)
一.概要 在 Unity入门教程(上) 中我们创建了一个游戏项目,并且创建了玩家角色和小球这些游戏对象,还通过添加游戏脚本实现了小方块的弹跳.虽然功能比较简单,但是完整地表现了使用Unity开发游戏的 ...
- Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE
Arduino可穿戴开发入门教程Windows平台下安装Arduino IDE Windows平台下安装Arduino IDE Windows操作系统下可以使用安装向导和压缩包形式安装.下面详细讲解这 ...
随机推荐
- nyoj 79-拦截导弹 (动态规划)
79-拦截导弹 内存限制:64MB 时间限制:3000ms 特判: No 通过数:9 提交数:11 难度:3 题目描述: 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个 ...
- SqlServer2005 查询 第八讲 order by
今天我们来说模糊查询 模糊查询 -- --模糊查询[主要用在搜索中]格式:select 字段的集合 from 表名 where 某个字段名 like 匹配条件 --注意:匹配条件通常含有通配符,通配符 ...
- 基于.NetStandard的简易EventBus实现-基础实现
一.问题背景 最近离职来到了一家新的公司,原先是在乙方工作,这回到了甲方,在这一个月中,发现目前的业务很大一部分是靠轮询实现的,例如:通过轮询判断数据处于B状态了,则轮询到数据后执行某种动作,这个其实 ...
- 关于IP网段划分
IP地址分类(A类 B类 C类 D类 E类) IP地址由四段组成,每个字段是一个字节,8位,最大值是255,, IP地址由两部分组成,即网络地址和主机地址.网络地址表示其属于互联网的哪一个网络 ...
- HTML页面插入图片,使用background还是img标签
很多新手在刚开始学习HTML标签的时候,老师一定会教你 <img src="xxx.png"/> 这种引入图片格式,第二天学习css的时候,老师又会教你给div等元素添 ...
- su root
1. 命令行方式 ansible zabbix_agents --become --become-method=su -K -m shell -a 'whoami' 2. 变量方式 [zabbix_a ...
- Web Scraper 翻页——利用 Link 选择器翻页 | 简易数据分析 14
这是简易数据分析系列的第 14 篇文章. 今天我们还来聊聊 Web Scraper 翻页的技巧. 这次的更新是受一位读者启发的,他当时想用 Web scraper 爬取一个分页器分页的网页,却发现我之 ...
- 小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- windows系统与SQL SERVER 2008数据库服务性能监控分析简要
软件系统性能测试体系流程介绍之windows系统与SQL SERVER 2008数据库服务性能监控分析简要 目前大部分测试人员对操作系统资源.中间件.数据库等性能监控分析都是各自分析各自的监控指标方式 ...
- element 根据某多个属性合并列
日常渲染 methods: { arraySpanMethod({ row, column, rowIndex, columnIndex }) { // 没办法循环判断具体是那一列 所以就只好写了多个 ...