0
点赞
收藏
分享

微信扫一扫

【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】391- MobX 入门教程(下)_初始化2019102301.png

在这个案例中,我们引用 ​​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"))

这些组件对应到我们最后页面效果如图:

【MobX】391- MobX 入门教程(下)_批量操作_022019102302.png

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>
}
}

这里需要注意:

  1. 可观察数据类型中的数组,实际上并不是数组类型,这里需要用​​observablePropTypes.observableArray​​ 去声明它的类型,对象也是一样。
  2. ​@observer​​ 在需要根据数据变换,而改变UI的组件去引用,另外建议有使用到相关数据的类都引用。
  3. 事实上,我们只需要记住​​observer​​ 方法,将所有 ​​React​​ 组件用 ​​observer​​ 修饰,就是 ​​react-mobx​​ 的用法。

4. 使用 Foo 组件

最后我们使用 ​​Foo​​​ 组件,需要给它传递两个参数,这样 ​​Bar​​ 组件才能拿到并使用:

ReactDOM.render(
<Foo cache={store.cache}
refresh={store.refresh}
/>,
document.querySelector("#root")
)

结尾

本文参考:

  • 《MobX 官方文档》
  • 茵风泳月《MobX 入门基础教程》

举报

相关推荐

0 条评论