mobx v6 + react hook 状态管理配置
react hook 风格下不再使用class类的形式定义组件,也就不再适用mobx以前版本的装饰器语法。以下分享 reack hook 语法风格下使用 mobx v6 版本的状态管理配置使用方式。相关依赖版本:"react": "^17.0.2","mobx": "^6.3.2","mobx-react-lite": "^3.2.2",一、mobxmobx 是 react 生态中常用的状态管理插
react hook 风格下不再使用class类的形式定义组件,也就不再适用mobx以前版本的装饰器语法。
以下分享 reack hook 语法风格下使用 mobx v6 版本的状态管理配置使用方式。
相关依赖版本:
"react": "^17.0.2",
"mobx": "^6.3.2",
"mobx-react-lite": "^3.2.2",
一、mobx
mobx
是 react 生态中常用的状态管理插件之一,特点是配置及使用方式比较简便,方式上和 vuex 有些相似。
官方中文文档:https://zh.mobx.js.org/react-integration.html
mobx-react-lite
是配合 react 使用的一个轻量化插件,只支持函数式组件,适合 react hook。
官方已不建议使用装饰器语法,主要原因是js装饰器在现在的 ES 规范中并不成熟(目前在stage-2提案阶段且迟迟无法推进),而且引入装饰器语法也会增加打包后的代码体积。这里也将完全放弃装饰器方式。
以下配置使用 react context 方式来传递数据,这也是官方推荐的方式。因为直接引用store原始数据在有多个module模块下可能会使引用变得杂乱,管理维护困难且不利于单元测试。
二、配置
先安装依赖:npm i -S mobx mobx-react-lite
1、配置 store/model
创建 根store src/store/index.js
:
import User from './modules/user'
export default {
userStore: new User(),
}
创建 User模块 src/store/modules/user.js
import { makeAutoObservable } from 'mobx'
export default class User {
constructor () {
/**
* state
*/
this.ticket = '' // 登录凭证ticket
makeAutoObservable(this)
}
/**
* computed
*/
get isLogin () {
return !!this.ticket
}
/**
* action
*/
setTicket (val) {
this.ticket = val || ''
}
}
- makeAutoObservable 会将你定义的数据自动转化为相应类型的可观察对象,例如 constructor 里定义的转化为 state,get 定义的函数转化为 computed,非 get 定义的函数转化为 action。
2、配置 context
创建 store 状态管理的 context 文件 src/contexts/storeContext.js
:
import React from 'react'
import store from '@/store'
const storeContext = React.createContext(store)
export default storeContext
- createContext函数参数为默认值,ts下需要。
- 使用 react context 向下级传递,来共享全局可观察数据。
- 引用方式在下面。
3、配置 hook
创建 store 状态管理的 hook 文件 src/hooks/storeHook.js
:
import { useContext } from 'react'
import StoreContext from '@/contexts/storeContext'
import { observer } from 'mobx-react-lite'
function useStore () {
const store = useContext(StoreContext)
return store
}
export {
observer,
useStore,
}
- 导出的 useStore 用于获取store数据。后续页面或组件都通过引用这个hook来获取store数据。
- 导出的 observer 用于监听store数据的改变,同步到组件数据中。后续页面或组件如需要响应store数据的变化,就引用它包裹一下页面或组件的默认导出函数即可。
- 这里将 mobx-react-lite 的 observer 在hook里导出是为了使用方便,一个hook就能引入全部所需。
4、引入 store
项目入口文件 src/index.js
里引用:
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import StoreContext from '@/contexts/storeContext'
import store from '@/store'
ReactDOM.render(
<React.StrictMode>
<StoreContext.Provider value={store}>
<App />
</StoreContext.Provider>
</React.StrictMode>,
document.getElementById('root')
)
三、使用
1、获取/响应 store 数据
示例组件 src/App.jsx
:
import { useStore, observer } from '@/hooks/storeHook'
function App () {
const { userStore } = useStore()
function onSetStore () {
userStore.setTicket('ttt')
}
return (
<div>
<p>ticket:{userStore.ticket}</p>
<button onClick={onSetStore}>修改store中的ticket</button>
</div>
)
}
export default observer(App)
- 通过自定义的 storeHook 来使用 store 的数据。
- 如果只是获取一次 store 的数据而无需响应 store 数据的变化,只需要引用 useStore 即可。
- 如果需要响应 store 数据的变化,即时更新到视图,就需要引用 observer,然后包裹一下该页面或组件的默认导出函数,即可实现响应式。
2、普通 js 中使用
- 普通js,就是非页面或组件的js里,没办法使用hook。
- 不过其实使用hook方式的目的就是能实现store数据的响应式。
- 普通js里不需要数据响应式,直接引入原始store文件就行。
示例 js src/http/axios.js
:
import axios from 'axios'
import store from '@/store'
const { userStore } = store
const service = axios.create()
service.interceptors.request.use(
(config) => {
config.headers = {
...config.headers,
ticket: userStore.ticket,
}
return config
},
err => {
Promise.reject(err)
}
)
export default service
- 以上实现一个简易的axios请求配置,实现效果就是在请求头headers里统一携带ticket参数,参数值从
src/store/index.js
文件里直接取。 - 如要修改store数据用法也一样,调用 userStore.setTicket() 即可。
四、总结
通过这种方式配置后,状态管理的使用将变得简单高效,完美兼容 react hook 语法,和 ts 配合也不再有障碍。
更多推荐
所有评论(0)