mobx中跟新了数据视图没变化_高级Web开发必备:Mobx入门和进阶

36dee1e289c64aa6ffdb5b8b507e94aa.png

Mobx 数据管理模式,通过行为修改状态,然后更新到视图。

  1. Mobx 的写法
  2. mobx 采用了ES7 语法的修饰器
function setAge(target){ target.age = 28;}@setAgeclass Person {}// 等同于Person = setAge(Person) || Person;console.log(Person.age);

利用装饰器代理函数使用起来更方便。 B格更高

  1. 常用的三个属性

observable 观察者

action 行为动作(唯一可以改变state)

computed 计算属性

const { observable, action, computed, autorun } = mobx;class Store { @observable list = []// 自动执行 @computed get total() { return this.list.length; }// 手动执行 @action change () { this.list.push(this.list.length); }};const mstore = new Store();setInterval(() => { mstore.change();}, 2000);autorun(() => { console.log(mstore.total);});

核心部分

  1. 可观察状态(State)
  2. @observable 修饰器将其中的属性转变为可观察的状态值
@observable classProperty = value

@observable 接受任何类型的 js 值(原始类型、引用、纯对象、类实例、数组和、maps),observable 的属性值在其变化的时候 mobx 会自动追踪并作出响应。

调节器的配置:

@observable.deep (默认)对对象进行深拷贝;

@observable.shallow 它只对对象进行浅拷贝;

@observable.ref 禁用对象的自动转化,只转化其引用

@observable classProperty = { obj: { name: 'q' } } 

当 value 是一个对象类型值的时候,它会默认克隆该对象并且把其中每个属性变为可观察的值,这里默认是深拷贝,也就是说其对象的后代属性都会变成可观察的,当 classProperty.obj.name 改变的时候,在 MobX 中也是可以观察到并响应的;

  1. 追加属性的观察
  2. 这时需要使用 extendObservable 来扩展对象
const { observable, action, computed, autorun, extendObservable } = mobx;class Store { @observable oo = { name: 1 }};const mstore = new Store();extendObservable(mstore, { oo: { age: 0 }});var i = 1;setInterval(() => { mstore.oo.age = i++;}, 2000);autorun(() => { console.log(mstore.oo.age);});
  1. 计算属性值(Computed Values)

是一类衍生值,它是根据现有的状态或者其他值计算而来。

两个原则:

1、计算属性中尽可能地不对当前状态做任何修改;

2、任何可以通过现有状态数据得到的值都应该通过计算属性获取。

@computed get computesValue [function];
  1. 动作(Action)

在 MobX 中,对于 store 对象中可观察的属性值,在他们改变的时候则会触发观察监听的函数,这里注意两点:

该属性必须是定义的可观察属性(@observable)

它的值必须发生改变(和原值是不等的)

class Store { @observable list = [] @observable name = '2' @observable oo = { age: 1 }};const mstore = new Store();// 触发观察监听的函数mstore.list.push('1');// 或者mstore.name = 'h';// 或者mstore.oo.age = 12;// 这个情况下是不会触发观察,因为 age 属性并不可观察mstore.age = 10;// 这个情况下也不会触发观察,因为其值没有发生变化mstore.oo.age = 1;

存在异步行为,比如网络请求

import { observable, action } from "mobx";import axios from "axios";export default class Store { @observable authenticated; @observable authenticating; @observable items; @observable item; @observable testval; // 初始化 state constructor() { this.authenticated = false; this.authenticating = false; this.items = []; this.item = {}; this.testval = "Hello"; } async fetchData(pathname, id) { let { data } = await axios.get( `localhost:3000/${pathname}` ); data.length > 0 ? this.setData(data) : this.setSingle(data); } @action setData(data) { this.items = data; } @action setSingle(data) { this.item = data; } @action clearItems() { this.items = []; this.item = {}; } @action authenticate() { return new Promise((resolve, reject) => { this.authenticating = true; setTimeout(action(() => { this.authenticated = !this.authenticated; this.authenticating = false; resolve(this.authenticated); }), 100); }); }}
  1. 运行观察(autorun)

在上面的例子中,当触发了可观察状态属性的改变后,其变化的监听则是在传入 autorun 函数中作出响应。

autorun 接受一个函数作为参数,在使用 autorun 的时候,该函数会被立即调用一次,之后当该函数中依赖的可观察状态属性(或者计算属性)发生变化的时候,该函数会被调用,注意,该函数的调用取决的函数中使用了哪些可观察状态属性(或者计算属性)。

React 中使用 MobX​​​​​​​

在实际使用中,autorun 中的函数就是用来操作 Reactions 的,当可观察状态属性的值发生改变的时候,可以在该函数中利用状态值来更新改变 UI 视图(记录日志、持久化),在 MobX 结合 React 的使用中,mobx-react 库则是封装了 autorun 用来在 store 中的可观察状态属性值发生改变的时候 rerender React 组件。

核心

@Provider

Provider 组件用来包裹最外层组件节点,并且传入 store(通过)context 传递给后代组件:

import { Provider } from 'mobx-react';const stores = { ...};ReactDOM.render(( ), document.getElementById('root'));

@inject、@observer

@inject 给组件注入其需要的 store(利用 React context 机制);

@observer 将 React 组件转化成响应式组件,它用 mobx.autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件:

import React from 'react';import { inject, observer } from 'mobx-react';@inject('userStore', 'commonStore')@observerexport default class App extends React.Component { componentWillMount() { if (this.props.commonStore.token) { this.props.userStore.pullUser() .finally(() => this.props.commonStore.setAppLoaded()); } else { this.props.commonStore.setAppLoaded(); } } render() { if (this.props.commonStore.appLoaded) { return ( 
... {this.props.children}
); } return ( ... ); }}

TIP:

在 mobx 中,可以有很多种方式去修改 state,mobx 并不对其做限制;

但是如果使用了严格模式:

import { useStrict } from 'mobx';useStrict(true);

总结

MobX 的理念是通过观察者模式对数据做出追踪处理,在对可观察属性的作出变更或者引用的时候,触发其依赖的监听函数,在 React 中既是在 @observer 中对组件进行数据更新并渲染到视图层面,其核心与开发模式和 Vue 非常相似。

相比于 Redux 纯函数的形式,它在代码层面却是给开发者减少了不少工作量,但在多人维护的大项目中,个人认为还是 Redux 更加有利,一旦项目中的数据交互增多,其在 MobX 中对于数据流的变化就变得难以理清,而只能依靠约定来限制触发场景。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值