Mobx 状态管理
可以少去理解一些不必要的概念,而多去思考为什么会有这样的东西,它解决了什么问题,或者它的运行机制是什么?1. mobx 介绍
https://cn.mobx.js.org/
1)mobx 是一个功能强大,上手非常容易的状态管理工具。
2)mobx 背后的哲学很简单:任何源自应用状态的东西都应该自动获取。
3)mobx 利用 getter 和 setter 来收集组件的数据依赖关系,从而在数据发生变化的时候精确知道哪些组件需要重绘,在界面规模变大的时候,往往会有很多细粒度更新。
2. mobx 与 redux 的区别
[*]mobx 写法上更偏向于 OOP。
[*]对一份数据直接进行修改操作,不需要始终返回一个新的数据。
[*]并非单一 store,可以多 store。
[*]Redux 默认以 Javascript 原生对象形式存储数据,而 Mobx 使用可观察对象。
优点:
[*]学习成本小。
[*]面向对象编程,而且对 TS 友好。
缺点:
[*]过于自由:mobx 提供的约定及模版代码很少,代码编写很自由,如果不做一些约定,比较容易导致团队代码风格不统一。
[*]相关的中间件很少,逻辑层业务整合是问题。
3. mobx 的使用
对普通类型数据的监听。对复杂类型(对象、数组等)数据的监听。
3.1 observable 和 autorun
observable 是把一个普通类型的数据,或者对象、数组复杂的数据转换为可观察的对象或数组。然后等你每次改这个值的时候,autorun 中监听函数就会被触发,所以 autorun 可以认为是一个监听者一样自动执行函数。
// 对普通函数的监听
import { observable, autorun } from 'mobx'
var observableNumber = observable.box(10)
// 第一次执行,之后每次改变也会执行
autorun(()=>{
console.log(observableNumber.get())
})
setTimeout(()=>{
observableNumber.set(20)
},1000)
// 对复杂类型(对象、数组等)数据的监听
const map = observable.map({key: 'value'})
const map = observable({key: 'value'})
const list = observable()应用示例:
// store.js
import { observable } from 'mobx'
const store = observable({
isTableShow: true,
list:[]
cityName:"hz"
})
// 修改
store.isTableShow = true
// 监听获取
store.isTableShow3.2 configure 严格模式
严格模式(强制 action)下不允许在非 Actions 以外的地方修改可观察对象的值。进行约束代码,集中在 store 中管理,特别在团队合作开发的时候。
// store.js
import { observable, configure } from 'mobx'
configure({
enforeActions:'always' // never 非严格模式,always 严格模式
})
const store = observable({
isTableShow: true,
list:[]
cityName:"hz"
changeShow() {
this.isTableShow = true
}
changeHide() {
this.isTableShow = false
}
},{
changeShow:action,
changeHide:action// 标记两个方法是 action,专门修改可观察的 value
})
// 修改 - 报错
//store.isTableShow = true
store.changeHide()
// 监听获取
store.isTableShow3.3 Mobx 新语法写法之装饰器
ES7 中提供装饰器语法 @ 符号。把一个普通的函数传递给装饰器函数,返回一个更强大的函数。
为了支持装饰器语法需要进行以下相关配置,包括编译器支持配置和脚手架(工程)支持启用装饰器语法配置。
import (observable, action, configure, runInAction} from 'mobx';
configure({enforceActions: 'always'})
//严格模式,必须写action,如里是fever,可以不写action。最好设置always,防止任意地方修改值,降低不确定性。
class Store {
@observable number = 0;
@observable name = "kerwin";
@action add = 0 => {
this. number++;
}//action只能影响正在运行的函数,而无法影响当前函数调用的异步操作
@action load = async()=>{
const data = await getData;
runInAction(() => {
this.name = data.name;
});
}// runInAction 解决异步问題
const newstore = new Store();
newstore.add();1)编译器配置 VSCode
对不属于任何工程的 JavaScript 文件启用或禁用 experimentalDecorators 设置。
2)脚手架(工程)支持启用装饰器语法
安装相关文件
npm i @babel/core @babel/plugin-proposal-decorator$ @babel/preset-env工程文件下创建 .babelrc
{
"presets": [
"@babel/preset-env"
].
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
]
]
}工程文件下创建 config-overrides.js
const path = require ('path")
const { override, addDecoratorsLegacy } = require ('customize-cra')
function resolve (dir) {
return path. join(__dirname, dir)
}
const customize = () => (config, env) => {
config. resolve.alias['@'] = resolve ('src")
if (env === 'production') {
config.externals = {
'react': 'React',
'react-dom': 'ReactDOM'
}
}
return config
};
module. exports = override (addDecoratorsLegacy, customize ))安装依赖,修改 package.json 中脚手架启动方式
npm i customize-cra react-app-rewired"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},3.4 Mobx 异步处理 runInAction
store 中在 action 里处理异步请求,异步请求结果回来后直接修改可观察对象中的数据,会报运行时错误,提示严格模式下不允许在 action 外部修改 ??? 异步函数的问题,异步结果修改会认为是在不知名的函数中修改了数据,必须引入 runInAction。
runInAction(()=>{
// 在这里修改数据
})3.5 Mobx 取消观察
取消观察是为了避免组件页面切换过程中多次进行监听。
var unsubscribe = autorun(()=>{
console.log(observableNumber.get())
})
// 取消观察
unsubscribe()4. mobx-react
mobx-react 让 Mobx 不用自己订阅和取消订阅,和 react-redux 一样。安装 npm i mobx-react。其原理也是构建一个高阶组件 (mobx-react 提供的)提供订阅和取消订阅功能。
1)类组件使用:
<Provider Store={store}>
</Provider>
@inject("store") // 注入 store 给组件,仅仅指在组件中可以用
@observer // 高阶组件帮你自动监听和取消订阅
class App extends Component {
// store 通过 this.props 传给组件
}2)函数式组件使用:
return(
<Observer> // 帮你监听订阅 autorun 和取消订阅
{ // 需要自己引入 store 使用
()=>{
return ...
}
}
</Observer>
)
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]