目录
什么是mobx
一个比redux简便的状态管理工具
装饰器babel
安装和注册装饰器
- 安装装饰器
npm i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties -D
- 在vite.config.js中注册装饰器
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react({
babel: {
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
],
},
}),
],
})
完成装饰器注册后,需要重启一次项目
理解装饰器
如下的代码,可以在控制台,看到Home这个类组件有个名为study的函数,@addFun
这个装饰器,相当于起了和Home=addFun(Home)
这句代码一样的作用。
注意:vscode中直接写装饰器会报错,在vscode的设置中搜索Experimental Decorators
,启用这个选项即可。
import React, { Component } from "react"
function addFun(ele) {
ele.prototype.study = () => {
console.log("新增的类方法")
}
return ele
}
@addFun
class Home extends Component {
render() {
console.log(this)
return (
<div>
<h1>主页</h1>
</div>
)
}
}
export default Home
mobx
安装mobx
npm i mobx
npm i mobx-react
定义store
在src下新建store文件夹,在store下新建文件index.js,文件中代码如下:
import { makeAutoObservable } from "mobx"
/* mobx6以上版本的定义store方式 */
class Store {
constructor() {
// 自动观察所有的state变量
makeAutoObservable(this)
}
//定义一个state变量
count = 0
// 定义一个action
incrementCount() {
this.count += 1
}
}
/* mobx6以下版本的定义store方式 */
// import { observable,action } from "mobx"
// class Store {
// //定义一个state变量
// @observable count = 0
// // 定义一个action
// @action incrementCount() {
// this.count+=1
// }
// }
const store = new Store()
export default store
项目全局注册store
在main.jsx中做如下修改:
import React from "react"
import ReactDOM from "react-dom/client"
import App from "./App"
import "./index.css"
import store from "./store"
import { Provider } from "mobx-react"
ReactDOM.createRoot(document.getElementById("root")).render(
<Provider store={store}>
<App />
</Provider>
)
在类组件中使用mobx的store
注意,observer装饰器的作用
import React, { Component } from "react"
import { Link } from "react-router-dom"
// 引入store
import store from "../store"
import { observer } from "mobx-react"
/* store中的方法调用并改变state中的变量后,组件不会重新render,
使用mobx-react中的observer装饰组件可以解决这个问题 */
@observer
class ClassEle extends Component {
render() {
return (
<div>
<h1>类组件页面</h1>
<Link to="/fun">go fun页面</Link>
<div>
<p>计数器</p>
{/* 使用store中的变量和函数 */}
<button onClick={() => store.incrementCount()}>{store.count}</button>
</div>
</div>
)
}
}
export default ClassEle
在函数组件中使用mobx的store
import React from "react"
import { Link } from "react-router-dom"
import store from "../store"
import { observer } from "mobx-react"
const FunEle = () => {
return (
<div>
<h1>函数组件页面</h1>
<Link to="/class">go class页面</Link>
<div>
<p>计数器</p>
{/* 使用store中的变量和函数 */}
<button onClick={() => store.incrementCount()}>{store.count}</button>
</div>
</div>
)
}
// 使用observer包裹函数组件,解决state中变量改变后,不自动render的问题
export default observer(FunEle)
store与本地存储结合
对store/index.js进行如下改写:
import { makeAutoObservable } from "mobx"
// mobx6以上版本的定义store方式
class Store {
constructor() {
// 自动观察所有的state变量
makeAutoObservable(this)
}
//定义一个state变量
count = 0 || localStorage.getItem("count")
// 定义一个action
incrementCount() {
this.count += 1
localStorage.setItem("count", this.count)
}
}
const store = new Store()
export default store