嘉兴做微网站多少钱,建设局是做什么的,上海公司网站建设,品牌建设网站公司mobx介绍
mobx是一个功能强大#xff0c;上手容易的状态管理工具。MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。利用getter和setter来收集组件的数据依赖关系#xff0c;从而在数据发生变化的时候精确知道哪些组件需要重绘。
mobx和redux的区别
mobx更…mobx介绍
mobx是一个功能强大上手容易的状态管理工具。MobX背后的哲学很简单:任何源自应用状态的东西都应该自动地获得。利用getter和setter来收集组件的数据依赖关系从而在数据发生变化的时候精确知道哪些组件需要重绘。
mobx和redux的区别
mobx更趋向于面向对象编程OOP对一份数据直接进行修改操作不需要始终返回一个新的数据并非单一store可以多storeredux默认以javascript原生对象形式存储数据而mobx使用的是可观察对象
优缺点
优点
学习成本小面向对象编程对TS友好
缺点
mobx过于自由提供的约束和模板代码很少代码编写自由如果不做一些约定比较容易导致团队代码风格不同一相关的中间件很少逻辑层业务整合是问题
mobx原则
MobX 支持单向数据流也就是动作改变状态而状态的改变会更新所有受影响的视图。 当状态改变时所有衍生都会进行原子级的自动更新。因此永远不可能观察到中间值。 所有衍生默认都是同步更新。这意味着例如动作可以在改变状态之后直接可以安全地检查计算值。
mobx安装
yarn add -D mobx mobx-reactmobx的简单使用
import {observable,autorun} from mobxobservable负责将数据转换为可观察的对象或者数组 每次改数据时就会在autorun的回调函数中触发autorun相当于监听者。
对于普通数据的监听
// 对于普通数据的监听
let observableGender observable.box(男);
// 监听变化(第一次必须执行之后每次改变也会执行)
autorun(() {console.log(observableNumber: , observableGender.get());
});
// 设置
setTimeout(() {observableGender.set(女);
}, 1000);组件第一次渲染时autorun会自动执行一次如上例以后每次相关可观察值改变都会打印1次。
注意在vconsole中可以看到mobx警告。 [MobX] Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed mobx由于启用了严格模式因此不允许在不使用action的情况下直接更改观察到值。异步的函数不能直接更改数据。 要更改可观察值需要通过action触发。
对于对象的监听
// 对于对象的监听-------
let observableObj observable.map({name: wuqing,age: 30,
});
autorun(() {console.log(observableObj对象属性name:, observableObj.get(name));
});
setTimeout(() {// 只会打印1次autorun只会监听与其相关的属性// observableObj.set(age, 100);observableObj.set(name, wuqing1);
}, 3000);autorun只会监听与其相关的属性 对象监听另外一种写法
let observableObj observable({name: wuqing,age: 30,
});
autorun(() {console.log(observableObj对象属性name:, observableObj.name);
});
setTimeout(() {observableObj.namewuqing1;
}, 3000);为了代码风格统一可以开启严格模式。
配置enforceActions: ‘always’等于开启严格模式必须用action触发数据更新。 若配置never则不会启用。
import { observable, configure } from mobx;// 严格模式
configure({enforceActions: always,
});const store observable({showMessage: false,name: 张伟,
});export default store;配置严格模式后若不通过action直接修改store数据会报错 Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed.
严格模式默认应该是开启的。
可观察值只允许通过action方法改不能直接改
import { observable, configure, action } from mobx;
// 严格模式
configure({enforceActions: always,
});
const store observable({showMessage: false,name: 张伟,changeNameAction() {// 可观察值name的方法this.name 刘德华;},},{changeNameAction: action, // 标记action是用于专门修改可观察值name的方法}
);
export default store;上面换一种写法用ES7注解器的写法是 observable和action都是装饰器通俗来说装饰器是将传入的值或者函数进行处理从而返回更加强大的值或者函数。
class Store {observable name 张伟;observable showMessage false;action changeNameAction() {// 可观察值name的方法this.name 刘德华 Math.random();console.log(aaaa--, this.name);}
}// 单例模式无论谁导入都是同一个对象
const store new Store();export default store;到这里会发现react如果没有经过配置直接使用decorators装饰器语法会报错 Support for the experimental syntax ‘decorators’ isn’t currently enabled 因为react默认是不支持装饰器语法需要做一些配置来启用装饰器语法。
step1:
在 tsconfig.json 中启用编译器选项 “experimentalDecorators”: true vscode点击设置输入搜索experimentalDecorators
step2:
安装支持修饰器所需依赖。
yarn add -D babel/core babel/plugin-proposal-decorators babel/preset-env创建.babelrc文件配置
{presets: [babel/preset-env],plugins: [[babel/plugin-proposal-decorators,{legacy: true}]]
}step3:
安装依赖
yarn add -D customize-cra react-app-rewired在项目根目录下创建 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())
step4:
修改package.json文件中 scripts 脚本。
scripts: {start: react-app-rewired start,build: react-app-rewired build,test: react-app-rewired test,eject: react-scripts eject}上面4个步骤配置完成后如果mobx修饰器还是不起作用就可能是mobx版本有问题执行step5。
step5
执行下面命令
yarn add -D mobx5 mobx-react5执行到step5就能成功使用mobx修饰器了。
注意如果报错 Parsing error: Cannot use the decorators and decorators-legacy plugin together 可以创建.eslintrc.js文件配置即可解决eslint报错问题
parserOptions: {parser: babel-eslint,ecmaFeatures: {// 支持装饰器legacyDecorators: true,},},mobx核心API介绍
observable observable是将类属性等进行标记实现对其的观察。 actions动作通过action改变state。action函数是对传入的function进行一次包装使得function中的observable对象的变化能够被观察到从而触发相应的衍生。 autoRun当你想创建一个响应式函数但是该函数永远没有观察者此时使用autorun。这通常是当你需要从反应式代码桥接到命令式代码的情况例如打印日志、持久化或者更新UI的代码。 当使用 autorun 时所提供的函数总是立即被触发一次然后每次它的依赖关系改变时会再次被触发。 相比之下computed(function) 创建的函数只有当它有自己的观察者时才会重新计算否则它的值会被认为是不相关的。 经验法则如果你有一个函数应该自动运行但不会产生一个新的值请使用autorun。 其余情况都应该使用 computed。 装饰器 runInAction工具函数是创建异步action的一种方式。 action只会对当前包装/装饰的函数做出反应而不会对当前运行函数所调用的函数不包含在当前函数之内作出反应这意味着如果 action 中存在 setTimeout、promise 的 then 或 async 语句并且在回调函数中某些状态改变了那么这些回调函数也应该包装在 action 中。 observable 定义 state computed 可以定义在相关数据发生变化时自动更新的值像这样的计算可以类似于 MS Excel 这样电子表格程序中的公式。每当只有在需要它们的时候它们才会自动更新。 action 定义操作 state 的方法。 observer 用来将 React 组件转变成响应式组件。observer 是由单独的 mobx-react 包提供的。 inject 将组件连接到提供的 stores。 mobx-react 包还提供了 Provider 组件它使用了 React 的上下文(context)机制可以用来向下传递 stores。 要连接到这些 stores需要传递一个 stores 名称的列表给 inject这使得 stores 可以作为组件的 props 使用。
使用
新建store.js封装Store Class专门用于状态管理再export Store的实例对象store。
import { action, configure, observable, runInAction } from mobx;
// 严格模式
configure({enforceActions: always,
});
class Store {observable name 张伟;observable showMessage false;observable messageList [];action changeNameAction() {// 可观察值name的方法this.name 刘德华 Math.random();}action async getMessageList() {const datas await getMessageListApi();// 异步runInAction((){this.messageListdatas})}
}
// 单例模式无论谁导入都是同一个对象
const store new Store();export default store;function getMessageListApi() {return new Promise((resolve) {return setTimeout(() {const list [];for (let i 0; i 5; i) {list.push(MSG-${Math.random()});}resolve(list);}, 1500);});
}从mobx-react中引入Provider全局注册并注入store实例内部组件就能使用到store中的state
import { Provider } from mobx-react;
import store from ./mobx-demo/Store/store-1;
const root ReactDOM.createRoot(document.getElementById(root));
root.render(// store属性名自命名为了区别写了一个demo名Provider demoStore{store}App //Provider
);内部组件需要使用state时先要用inject装饰器注入store再用observer将组件标记为 observer当组件中使用到的store state发生变化时组件会自动响应更新。
inject(demoStore) // 通过inject修饰器注入store
observer
export default class App extends Component {componentDidMount() {console.log(name--, this.props.demoStore.name);}render() {return RouterProvider router{routes}/RouterProvider;}
}