Mobx介绍
一个可以和React良好配合的集中状态管理工具,和Redux解决的问题相似,都可以独立组件进行集中状态管理
![2022-10-20T08:31:15.png 2022-10-20T08:31:15.png](https://pan.pigeoooon.cool/d/imgs/blog/loading.gif)
优势
- 简单,编写无模板的极简代码精准描述你的意图
- 轻松实现最优渲染,依赖自动追踪,实现最小渲染优化
- 架构自由,可移植, 可测试 无特殊心智负担
配置开发环境
Mobx是一个独立的响应式的库,可以独立于任何UI框架存在,但是通常大家习惯把它和React进行绑定使用,用Mobx来做响应式数据建模,React作为UI视图框架渲染内容,我们环境的配置需要三个部分
1、一个create-react-app创建好的React项目环境
2、mobx框架本身
3、一个用来链接mobx和React的中间件
1 2
| $ yarn add mobx mobx-react-lite
|
基础使用
1. 初始化mobx
初始化步骤:
1、定义数据状态state
2、在构造器中实现数据响应式处理 makeAutoObservble
3、定义修改数据的函数action
4、实例化store并导出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { makeAutoObservable } from 'mobx'
class CounterStore { count = 0 constructor() { makeAutoObservable(this) } addCount = () => { this.count++ } }
const counter = new CounterStore() export default counter
|
2. React使用store
实现步骤:
1、在组件中导入counterStore实例对象
2、在组件中使用storeStore实例对象中的数据
3、通过事件调用修改数据的方法修改store中的数据
4、让组件响应数据变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import counterStore from './store'
import { observer } from 'mobx-react-lite' function App() { return ( <div className="App"> <button onClick={() => counterStore.addCount()}> {counterStore.count} </button> </div> ) }
export default observer(App)
|
计算属性(衍生状态)
概念: 基于一个原始的数据,经过特定的计算,得到一个新的数据,且能在原始的数据发生变化的时候,他同时进行重新计算。
![2022-10-20T08:36:15.png 2022-10-20T08:36:15.png](https://pan.pigeoooon.cool/d/imgs/blog/loading.gif)
实现步骤:
- 声明一个存在的数据
- 通过get关键词 定义计算属性
- 在 makeAutoObservable 方法中标记计算属性
conterStore.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import { computed, makeAutoObservable } from 'mobx'
class CounterStore { list = [1, 2, 3, 4, 5, 6] constructor() { makeAutoObservable(this, { filterList: computed }) } changeList = () => { this.list.push(7, 8, 9) } get filterList () { return this.list.filter(item => item > 4) } }
const counter = new CounterStore()
export default counter
|
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import counterStore from './store'
import { observer } from 'mobx-react-lite' function App() { return ( <div className="App"> {/* 原数组 */} {JSON.stringify(counterStore.list)} {/* 计算属性 */} {JSON.stringify(counterStore.filterList)} <button onClick={() => counterStore.changeList()}>change list</button> </div> ) }
export default observer(App)
|
异步数据处理
测试接口: http://geek.itheima.net/v1\_0/channels
实现步骤:
1、在mobx中编写异步请求方法 获取数据 存入state中
2、组件中通过 useEffect + 空依赖 触发action函数的执行
channelStore.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
import { makeAutoObservable } from 'mobx' import axios from 'axios'
class ChannelStore { channelList = [] constructor() { makeAutoObservable(this) } setChannelList = async () => { const res = await axios.get('http://geek.itheima.net/v1_0/channels') this.channelList = res.data.data.channels } } const channlStore = new ChannelStore() export default channlStore
|
App.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import { useEffect } from 'react' import { useStore } from './store' import { observer } from 'mobx-react-lite' function App() { const { channlStore } = useStore() useEffect(() => { channlStore.setChannelList() }, []) return ( <ul> {channlStore.channelList.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> ) }
export default observer(App)
|
模块化
场景: 一个项目有很多的业务模块,我们不能把所有的代码都写到一起,这样不好维护,提了提供可维护性,需要引入模块化机制
![2022-10-20T08:39:30.png 2022-10-20T08:39:30.png](https://pan.pigeoooon.cool/d/imgs/blog/loading.gif)
实现步骤:
- 拆分模块js文件,每个模块中定义自己独立的state/action
- 在store/index.js中导入拆分之后的模块,进行模块组合
- 利用React的context的机制导出统一的useStore方法,给业务组件使用
1、定义task模块
store/taskStore.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import { makeAutoObservable } from 'mobx'
class TaskStore { taskList = [] constructor() { makeAutoObservable(this) } addTask () { this.taskList.push('vue', 'react') } }
const task = new TaskStore()
export default task
|
2、定义counterStore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import { makeAutoObservable } from 'mobx'
class CounterStore { count = 0 list = [1, 2, 3, 4, 5, 6] constructor() { makeAutoObservable(this) } addCount = () => { this.count++ } changeList = () => { this.list.push(7, 8, 9) } get filterList () { return this.list.filter(item => item > 4) } }
const counter = new CounterStore()
export default counter
|
3、组合模块导出统一方法
store/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React from 'react'
import counter from './counterStore' import task from './taskStore'
class RootStore { constructor() { this.counterStore = counter this.taskStore = task } }
const rootStore = new RootStore()
const context = React.createContext(rootStore)
const useStore = () => React.useContext(context)
export { useStore }
|
4、组件使用模块中的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import { observer } from 'mobx-react-lite'
import { useStore } from './store' function App() { const store = useStore() return ( <div className="App"> <button onClick={() => store.counterStore.addCount()}> {store.counterStore.count} </button> </div> ) }
export default observer(App)
|