状态管理库 MobX 和 react

简介:

MobX

  • MobX 是一个简单、方便扩展、久经考验的状态管理解决方案

基本概念

  • MobX 是一个独立的组件,可以配合各种框架使用,由于项目中需要使用 react & MobX。下面来详细了解一下

  • State 是每一个应用程序的核心部分,而使用一个不合规范的 State 则是让你的应用充满 bug 和失控的不二法门,或者就是局部变量环绕,让你的 state 失去了同步。有很多框架试图解决这个问题,比如使用不可变的 state,但是这样以来又带来了新的问题,比如数据必须规格化,完整性约束失效等等。

MobX 功能

  • MobX 让整个事情又变简单了:它不允许产生失控的 state。它的理念也很简单:所有可以从 state 中派生的事物,都会自动的派生。

  • demo



class TodoStore {
	todos = [];

	get completedTodosCount() {
    	return this.todos.filter(
			todo => todo.completed === true
		).length;
    }

	report() {
		if (this.todos.length === 0)
			return "<none>";
		return `Next todo: "${this.todos[0].task}". ` + 
			`Progress: ${this.completedTodosCount}/${this.todos.length}`; 
	}

    addTodo(task) {
		this.todos.push({ 
			task: task,
			completed: false,
            assignee: null
		});
	}
}

const todoStore = new TodoStore();


当我们去创建一个 todoStore,他拥有一个 todos 集合,现在我们往这个 todoStore 里添加一些东西,为了明显起见,就调用 todoStore.report



todoStore.addTodo("read MobX tutorial");
console.log(todoStore.report());
​
todoStore.addTodo("try MobX");
console.log(todoStore.report());
​
todoStore.todos[0].completed = true;
console.log(todoStore.report());
​
todoStore.todos[1].task = "try MobX in own project";
console.log(todoStore.report());
​
todoStore.todos[0].task = "grok MobX tutorial";
console.log(todoStore.report());


太巧了,这就是 MobX 能为你做的事情。 自动执行只在 state 改变的时候触发,就好像 Excel 中的图表只在单元格数据改变时更新一样。为了达到这个目标, TodoStore 必须成为可观测的( observable)才行,让我们来改一些代码。

observable & computed


同时,completedTodosCount 属性应该被自动派生,使用 @observable 和 @computed 装饰器来做这些事情:



class ObservableTodoStore {
    @observable todos = [];
    @observable pendingRequests = 0;
 
    constructor() {
        mobx.autorun(() => console.log(this.report));
    }
 
    @computed get completedTodosCount() {
    	return this.todos.filter(
			todo => todo.completed === true
		).length;
    }
 
    @computed get report() {
        if (this.todos.length === 0)
            return "<none>";
	return `Next todo: "${this.todos[0].task}". ` + 
	    `Progress: ${this.completedTodosCount}/${this.todos.length}`; 
	}
 
    addTodo(task) {
	this.todos.push({ 
	    task: task,
	    completed: false,
	    assignee: null
	});
    }
}
 
const observableTodoStore = new ObservableTodoStore();


在这个构造器中,我们使用 autorun 包裹了一个打出 report 的小函数。 Autorun 里的东西首先会运行一次,然后当其中的函数有 observable 的数据发生变化时,会再次运行。 这里我们使用了 todos 属性,每次 todos 变化了我们就打印出新的东西。 测试一下



observableTodoStore.addTodo("read MobX tutorial");
observableTodoStore.addTodo("try MobX");
observableTodoStore.todos[0].completed = true;
observableTodoStore.todos[1].task = "try MobX in own project";
observableTodoStore.todos[0].task = "grok MobX tutorial";



举个栗子(sf 的一个问题有感)

  • 对于单个对象,我可以使用computed通过计算获得一些属性,比如

@observable good = {
    number: 2,
    price: 3
}
@computed get totalPrice() {
    return this.good.number * this.good.price;
}

// 数组
@observable goodsList = [{
    number: 2,
    price: 3
},{
    number: 2,
    price: 3
}]

问题?

  • 这种情况我如何通过computed获得数组某个元素的计算属性呢,还是只能在改变number的函数中手动去更改,但是我数组的对象中并没有一个totalPrice的属性,每次把单个good push到goodsList中去还要给good添加一个totalPrice属性岂不是很麻烦

解决方案

  • good 弄成一个单独的model文件


export default class Good{
  @observable number;
  @observable price;
  constructor(number, price) {
    this.number = number;
    this.price = price;
  }
  
  @computed
  get totalPrice() {
    return this.number * this.price
  }   

}


    • 然后在goodList文件中
    • 这样就实现了自动计算, 访问的时候类似 this.props.goodList[0].totalPrice

  @action
  addGood(...args) {
    this.todos.push(new Good(...args));
  }


  • 未完待续...

总结

  • 最后总结一些:
  • @observale 修饰器或者 observable 函数让对象可以被追踪;
  • @computed 修饰器创造了自动运算的表达式;
  • autorun 函数让依靠 observable 的函数自动执行,这个用来写 log,发请求很不错;
  • @observer 修饰器让 React 组建自动起来,它会自动更新,即便是在一个很大的程序里也会工作的很好;
  • MobX 不是一个状态容器

很多人把 MobX 当作另外一个 Redux,但是它仅仅是一个库,不是一个什么架构。上面的例子还是需要程序员自己去组织逻辑和 store 或者控制器什么的.


引用:

10分钟极速入门 MobX

sf @computed使用

react 官网



原文发布时间为:2018年06月27日
原文作者: Pandaaa
本文来源: 掘金 如需转载请联系原作者

目录
相关文章
|
10天前
|
前端开发 JavaScript UED
React 图标库使用指南
本文详细介绍如何在 React 项目中使用 `react-icons` 等图标库,涵盖环境搭建、基础使用、常见问题与易错点、高级用法等内容,并通过代码案例进行说明。适合初学者和进阶开发者参考。
33 8
|
2月前
|
前端开发 JavaScript API
React开发需要了解的10个库
本文首发于微信公众号“前端徐徐”,介绍了React及其常用库。React是由Meta开发的JavaScript库,用于构建动态用户界面,广泛应用于Facebook、Instagram等知名网站。文章详细讲解了Axios、Formik、React Helmet、React-Redux、React Router DOM、Dotenv、ESLint、Storybook、Framer Motion和React Bootstrap等库的使用方法和应用场景,帮助开发者提升开发效率和代码质量。
122 4
React开发需要了解的10个库
|
2月前
|
资源调度 前端开发 JavaScript
React中classnames库使用
【10月更文挑战第7天】
|
2月前
|
前端开发 JavaScript API
利用React Hooks简化状态管理
【10月更文挑战第1天】利用React Hooks简化状态管理
|
2月前
|
存储 前端开发 JavaScript
利用React Hooks简化状态管理
【10月更文挑战第1天】利用React Hooks简化状态管理
38 3
|
27天前
|
资源调度 前端开发 JavaScript
React 测试库 React Testing Library
【10月更文挑战第22天】本文介绍了 React Testing Library 的基本概念和使用方法,包括安装、基本用法、常见问题及解决方法。通过代码案例详细解释了如何测试 React 组件,帮助开发者提高应用质量和稳定性。
40 0
|
2月前
|
前端开发 JavaScript 网络架构
实现动态路由与状态管理的SPA——使用React Router与Redux
【10月更文挑战第1天】实现动态路由与状态管理的SPA——使用React Router与Redux
34 1
|
3月前
|
前端开发
React技术栈-react使用的Ajax请求库实战案例
这篇文章介绍了在React应用中使用Axios和Fetch库进行Ajax请求的实战案例,展示了如何通过这些库发送GET和POST请求,并处理响应和错误。
59 10
React技术栈-react使用的Ajax请求库实战案例
|
3月前
|
前端开发
React技术栈-react使用的Ajax请求库用户搜索案例
这篇文章展示了一个React技术栈中使用Ajax请求库(如axios)进行用户搜索的实战案例,包括React组件的结构、状态管理以及如何通过Ajax请求获取并展示GitHub用户数据。
33 7
React技术栈-react使用的Ajax请求库用户搜索案例
|
3月前
|
前端开发 JavaScript API
深入探索React Hooks与状态管理
深入探索React Hooks与状态管理
47 2