找回密码
 立即注册
首页 业界区 安全 Mobx 状态管理

Mobx 状态管理

笃迩讦 2025-7-30 15:55:36
可以少去理解一些不必要的概念,而多去思考为什么会有这样的东西,它解决了什么问题,或者它的运行机制是什么?
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 可以认为是一个监听者一样自动执行函数。
  1. // 对普通函数的监听
  2. import { observable, autorun } from 'mobx'
  3. var observableNumber = observable.box(10)
  4. // 第一次执行,之后每次改变也会执行
  5. autorun(()=>{
  6.   console.log(observableNumber.get())
  7. })
  8. setTimeout(()=>{
  9.   observableNumber.set(20)
  10. },1000)
  11. // 对复杂类型(对象、数组等)数据的监听
  12. const map = observable.map({key: 'value'})
  13. const map = observable({key: 'value'})
  14. const list = observable([1,2,3])
复制代码
应用示例:
  1. // store.js
  2. import { observable } from 'mobx'
  3. const store = observable({
  4.   isTableShow: true,
  5.   list:[]
  6.   cityName:"hz"
  7. })
  8. // 修改
  9. store.isTableShow = true
  10. // 监听获取
  11. store.isTableShow
复制代码
3.2 configure 严格模式

严格模式(强制 action)下不允许在非 Actions 以外的地方修改可观察对象的值。进行约束代码,集中在 store 中管理,特别在团队合作开发的时候。
  1. // store.js
  2. import { observable, configure } from 'mobx'
  3. configure({
  4.   enforeActions:'always' // never 非严格模式,always 严格模式
  5. })
  6. const store = observable({
  7.   isTableShow: true,
  8.   list:[]
  9.   cityName:"hz"
  10.   changeShow() {
  11.           this.isTableShow = true
  12.         }
  13.         changeHide() {
  14.           this.isTableShow = false
  15.         }
  16. },{
  17.   changeShow:action,
  18.   changeHide:action  // 标记两个方法是 action,专门修改可观察的 value
  19. })
  20. // 修改 - 报错
  21. //store.isTableShow = true
  22. store.changeHide()
  23. // 监听获取
  24. store.isTableShow
复制代码
3.3 Mobx 新语法写法之装饰器

ES7 中提供装饰器语法 @ 符号。把一个普通的函数传递给装饰器函数,返回一个更强大的函数。
为了支持装饰器语法需要进行以下相关配置,包括编译器支持配置和脚手架(工程)支持启用装饰器语法配置。
  1. import (observable, action, configure, runInAction} from 'mobx';
  2. configure({enforceActions: 'always'})
  3. //严格模式,必须写action,如里是fever,可以不写action。最好设置always,防止任意地方修改值,降低不确定性。
  4. class Store {
  5.         @observable number = 0;
  6.         @observable name = "kerwin";
  7.         @action add = 0 => {
  8.                 this. number++;
  9.         }//action只能影响正在运行的函数,而无法影响当前函数调用的异步操作
  10.         @action load = async()=>{
  11.                 const data = await getData;
  12.                 runInAction(() => {
  13.                         this.name = data.name;
  14.                 });
  15. }// runInAction 解决异步问題
  16. const newstore = new Store();
  17. newstore.add();
复制代码
1)编译器配置 VSCode
对不属于任何工程的 JavaScript 文件启用或禁用 experimentalDecorators 设置。
2)脚手架(工程)支持启用装饰器语法
安装相关文件
  1. npm i @babel/core @babel/plugin-proposal-decorator$ @babel/preset-env
复制代码
工程文件下创建 .babelrc
  1. {
  2.   "presets": [
  3.           "@babel/preset-env"
  4.   ].
  5.   "plugins": [
  6.     [
  7.       "@babel/plugin-proposal-decorators",
  8.       {
  9.         "legacy": true
  10.       }
  11.     ]
  12.   ]
  13. }
复制代码
工程文件下创建 config-overrides.js
  1. const path = require ('path")
  2. const { override, addDecoratorsLegacy } = require ('customize-cra')
  3. function resolve (dir) {
  4.         return path. join(__dirname, dir)
  5. }
  6. const customize = () => (config, env) => {
  7.   config. resolve.alias['@'] = resolve ('src")
  8.   if (env === 'production') {
  9.     config.externals = {
  10.       'react': 'React',
  11.       'react-dom': 'ReactDOM'
  12.     }
  13.   }
  14.   return config
  15. };
  16. module. exports = override (addDecoratorsLegacy, customize ))
复制代码
安装依赖,修改 package.json 中脚手架启动方式
  1. npm i customize-cra react-app-rewired
复制代码
  1. "scripts": {
  2.   "start": "react-app-rewired start",
  3.   "build": "react-app-rewired build",
  4.   "test": "react-app-rewired test",
  5.   "eject": "react-app-rewired eject"
  6. },
复制代码
3.4 Mobx 异步处理 runInAction

store 中在 action 里处理异步请求,异步请求结果回来后直接修改可观察对象中的数据,会报运行时错误,提示严格模式下不允许在 action 外部修改 ??? 异步函数的问题,异步结果修改会认为是在不知名的函数中修改了数据,必须引入 runInAction。
  1. runInAction(()=>{
  2.         // 在这里修改数据
  3. })
复制代码
3.5 Mobx 取消观察

取消观察是为了避免组件页面切换过程中多次进行监听。
  1. var unsubscribe = autorun(()=>{
  2.   console.log(observableNumber.get())
  3. })
  4. // 取消观察
  5. unsubscribe()
复制代码
4. mobx-react

mobx-react 让 Mobx 不用自己订阅和取消订阅,和 react-redux 一样。安装 npm i mobx-react。其原理也是构建一个高阶组件 (mobx-react 提供的)提供订阅和取消订阅功能。
1)类组件使用:
  1. <Provider Store={store}>
  2.        
  3. </Provider>
  4. @inject("store") // 注入 store 给组件,仅仅指在组件中可以用
  5. @observer // 高阶组件帮你自动监听和取消订阅
  6. class App extends Component {
  7.   // store 通过 this.props 传给组件
  8. }
复制代码
2)函数式组件使用:
  1. return(
  2.        
  3.                 <Observer> // 帮你监听订阅 autorun 和取消订阅
  4.                   { // 需要自己引入 store 使用
  5.                            ()=>{
  6.                              return ...
  7.                     }
  8.                          }
  9.                 </Observer>
  10.        
  11. )
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册