阅读时间:大概在 3 分钟左右javascript
本文章旨在介绍Mobx,不对其余状态管理工具进行比较。html
Redux 开启了前端状态管理大门,可是对于一些比较小的应用,使用 Redux 反而增长了开发复杂度,这时候,我会选择使用 Mobx 来进行状态管理。前端
Mobx是一个经过函数响应式编程,让状态管理更加简单和容易拓展的库。java
它遵循一个最简单的原则:react
Anything that can be derived from the application state, should be derived. Automatically.git
(全部可以从应用状态得到的东西,都应该自动地被得到)github
他的原理很是简洁:编程
Mobx 为 JavaScript 自己已有的几种数据结构都添加了可观察的功能,也可使用ES6的新特性,经过装饰器来添加这些功能。数组
可观察的对象:网络
import {observable, autorun, action} from "mobx";
var person = observable({
// 可观察的属性
name: "John",
age: 42,
showAge: false,
// 计算后的属性
get labelText() {
return this.showAge ? `${this.name} (age: ${this.age})` : this.name;
},
// action
setAge: action(function(age) {
this.age = age;
})
});
// autorun 函数是来运行状态后更新后引起的 reaction
autorun(() => console.log(person.labelText));
person.name = "Dave";
// 输出: 'Dave'
复制代码
可观察的数组:
import {observable, autorun} from "mobx";
var todos = observable([
{ title: "Spoil tea", completed: true },
{ title: "Make coffee", completed: false }
]);
autorun(() => {
console.log("Remaining:", todos
.filter(todo => !todo.completed)
.map(todo => todo.title)
.join(", ")
);
});
todos[0].completed = false;
// 输出: 'Remaining: Spoil tea, Make coffee'
todos[2] = { title: 'Take a nap', completed: false };
// 输出: 'Remaining: Spoil tea, Make coffee, Take a nap'
todos.shift();
// 输出: 'Remaining: Make coffee, Take a nap'
复制代码
可观察的Map:
import {observable} from "mobx";
const map = observable.map();
map.set("a", 100);
console.log(map.get("a"))
// 输出: 100
map.observe(({name, newValue}) => console.log(name, "->", newValue))
map.set("b",100)
// 输出: b -> 100
复制代码
原生的值和引用:
import {observable} from "mobx";
const cityName = observable("Vienna");
console.log(cityName.get());
// 输出 'Vienna'
cityName.observe(function(change) {
console.log(change.oldValue, "->", change.newValue);
});
cityName.set("Amsterdam");
// 输出 'Vienna -> Amsterdam'
复制代码
状态管理中有一个重要的概念,状态应该以一种方式来更新。在Mobx之中,并不须要触发事件、调用分发函数或者相似的动做,状态的基本相应派发由 Mobx 自己来负责。
可是让Mobx全盘接管显然限制了可拓展性和可用性,因此Mobx提供了Actions来使用。Actions应该永远只对修改状态的函数使用动做。建议对任何修改 observables 或具备反作用的函数使用 (@)action
。 结合开发者工具的话,动做还能提供很是有用的调试信息。
Reactions 和计算值很像,但它不是产生一个新的值,而是会产生一些反作用,好比打印到控制台、网络请求、递增地更新 React 组件树以修补DOM、等等。 简而言之,reactions 在 响应式编程和命令式编程之间创建沟通的桥梁。
谈了那么多概念那么怎么在 React 里面使用呢。
observer
函数/装饰器能够用来将 React 组件转变成响应式组件。 它用 mobx.autorun
包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时均可以强制刷新组件。 observer
是由单独的 mobx-react
包提供的。
import {observer} from "mobx-react";
var timerData = observable({
secondsPassed: 0
});
setInterval(() => {
timerData.secondsPassed++;
}, 1000);
@observer class Timer extends React.Component {
render() {
return (<span>Seconds passed: { this.props.timerData.secondsPassed } </span> )
}
};
React.render(<Timer timerData={timerData} />, document.body);
复制代码
mobx 使用的时候,确保让observer渗透到最深处的组件,由于状态是向下传递的,若是原子组件没有加入Mobx的观察,那么就可能就没有效果。
拓展阅读