前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【MobX】391- MobX 入门教程(下)

【MobX】391- MobX 入门教程(下)

作者头像
pingan8787
发布2019-10-30 11:31:41
8880
发布2019-10-30 11:31:41
举报
文章被收录于专栏:前端自习课
三、MobX 常用 API 介绍

3. 修改可观察数据

在上一部分内容中,我们了解到,对可观察的数据做出反应的时候,需要我们手动修改可观察数据的值。这种修改是通过直接向变量赋值来实现的,虽然简单易懂,但是这样会带来一个较为严重的副作用,就是每次的修改都会触发 autorun 或者 reaction 运行一次。多数情况下,这种高频的触发是完全没有必要的。

比如用户对视图的一次点击操作需要很多修改 N 个状态变量,但是视图的更新只需要一次就够了。

为了优化这个问题, MobX 引入了 action

3.1 (@)action

action 是修改任何状态的行为,使用 action 的好处是能将多次修改可观察状态合并成一次,从而减少触发 autorun 或者 reaction 的次数。

可以理解成批量操作,即一次动作中包含多次修改可观察状态,此时只会在动作结束后,做一次性重新计算和反应。

action 也有两种使用方法,这里以 decorate 方式来介绍。

代码语言:javascript
复制
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.stringstore.number 两个变量后,再运行 store.bar() 会发现,控制台值输出一次 ["pingan", 100] ,这就说明 reaction 只被执行一次。

知识点:action.bound

另外 action 还有一种特殊使用方法:action.bound,常常用来作为一个 callback 的方法参数,并且执行效果也是一样:

代码语言:javascript
复制
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)() 的语法糖。

代码语言:javascript
复制
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 简单实例

这里以简单计数器为例,实现点击按钮,数值累加的简单操作,如图:

2019102301.png

在这个案例中,我们引用 mobx-react 库来实现,很明显可以看出 mobx-react 是作为 mobxreact 之前的桥梁。

它将 react 组件转化为对可观察数据的反应,也就是将组件的 render 方法包装成 autorun 方法,使得状态变化时能自动重新渲染。

详细可以查看:https://www.npmjs.com/package/mobx-react 。

接下来开始我们的案例:

1. 安装依赖和配置webpack

由于配置和前面第二节介绍差不多,所以这里会以第二节的配置为基础,添加配置。

首先安装 mobx-react 依赖:

代码语言:javascript
复制
cnpm i mobx-react -D

修改webpack.config.js,在 presets 配置中添加 react 进来:

代码语言:javascript
复制
// ... 省略其他
- 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 项目

这里初始化一下我们本次项目的简单骨架:

代码语言:javascript
复制
// 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"))

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

2019102302.png

2. 实现 Store 类

Store 类用于存储数据。

代码语言:javascript
复制
class Store {
    @observable cache = { queue: [] }
    @action.bound refresh(){
        this.cache.queue.push(1)
    }
}

3. 实现 Bar 和 Foo 组件

实现代码如下:

代码语言:javascript
复制
@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 组件才能拿到并使用:

代码语言:javascript
复制
ReactDOM.render(
  <Foo cache={store.cache} 
    refresh={store.refresh}
  />,
  document.querySelector("#root")
)

结尾

本文参考:

  • 《MobX 官方文档》
  • 茵风泳月《MobX 入门基础教程》
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端自习课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3. 修改可观察数据
    • 3.1 (@)action
    • 四、 Mobx-React 简单实例
      • 1. 安装依赖和配置webpack
        • 2. 初始化 React 项目
          • 2. 实现 Store 类
            • 3. 实现 Bar 和 Foo 组件
              • 4. 使用 Foo 组件
              • 结尾
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档