首先,经过深思熟虑、反复思考决定选择Mobx作为新项目的状态管理工具,原因主要为:Mobx贯彻了响应式编程,代码更加的轻量简洁,且天然支持多store独立共存。
这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
其实,想说技术选型需要经历无数的挣扎和反复的思考拿捏,然后选出那个你最喜欢的。当然参考了阿里巴巴大佬的文章:这可能是大型复杂项目下数据流的最佳实践。有了大佬的理论指导,我顿时信心倍增。
从设计领域模型开始
我们以简易的电商系统为例,比如需要我们关注几个领域:
- 用户(保存当前用户的信息)
- 订单(保存当前订单的信息)
- 通知(需要显示最新的通知信息,可能来自服务器端,也可能来自用户页面的一些操作如下了订单)
我们想实现这么几个交互:
- 点击下单成功后向通知store里添加一条记录
- 用户登陆(鉴权后)方可显示通知或订单。
根据需求我们可以设计store的层级:
- global-store(提供鉴权状态、token信息、通知)
- 用户(包含用户详情信息,以及登陆、登出方法)
- 订单
注意:我们约定:子级store只能跟父store交互,不可以同级或交叉引用,如果确实有交叉调用的需求,应该把其中的某些数据或状态提升到共同的上级。
到这里,我们还只是讨论设计,接下来我们用代码来演示一下实施细节
项目实战
首先配置公共store(share-store
)
// share-store
import { makeObservable, observable, action } from "mobx"
type LoginStatus = undefined|true|false;
export class ShareStore {
@observable authStatus:boolean = false;
@observable token:string = "";
@observable notifyList:Array<string> = [];
constructor() {
makeObservable(this);
}
//update loginStatus
@action
updateAuthStatus(state:boolean) {
this.authStatus = state;
}
@action
updateToken(token:string){
this.token = token;
}
@action addNotify(notify:string){
this.notifyList.push(notify)
}
}
export const shareStore = new ShareStore();
复制代码
接着是order-store
:
//order-store
import { makeObservable, observable, action } from "mobx"
import {shareStore,ShareStore} from '../shared-store'
type orderStatusType = "none"|"progressing"|"done"
export class OrderStore {
@observable orderStatus:orderStatusType = "none"
@observable orderName:string = "";
@observable orderType:"Book"|"Computer"|"" = "";
@observable rootStore:ShareStore;
constructor() {
makeObservable(this);
//将公共store注入
this.rootStore = shareStore;
}
@action
updateOrderStatus(state:orderStatusType) {
this.orderStatus = state;
}
@action
updateOrderInfo(state:any) {
this.orderType = state.type;
this.orderName = state.name;
}
@action
doOrder(payload:any){
//api request
//....
const msgName = "A new order occurs";
this.rootStore.addNotify(msgName);
}
}
export const orderStore = new OrderStore();
复制代码
再然后是user-store
:
//user-store
import { makeObservable, observable, action } from "mobx"
import {shareStore,ShareStore} from '../shared-store'
type UserInfoType = {
name:string,
gender:string,
level:number
}
export class UserStore {
@observable userInfo:UserInfoType = {
name:"",
gender:"",
level:0
}
@observable rootStore:ShareStore;
constructor() {
makeObservable(this);
this.rootStore = shareStore;
}
@action
updateUserInfo(state:UserInfoType) {
this.userInfo = state;
}
@action
doLogin(userName:string,password:string) {
//Api request send
//....
const result = {
name:"Andrew",
gender:"male",
level:100
}
this.updateUserInfo(result)
}
@action
doLogout(){
//get token
const token = this.rootStore.token;
//Api request send
//....
this.rootStore.updateAuthStatus(false)
}
}
export const userStore = new UserStore();
复制代码
最好我们配置store的入口文件,搭配contextAPI提供provider:
//index.ts
import {shareStore,ShareStore} from './shared-store'
import {orderStore,OrderStore} from './order/order'
import {userStore,UserStore} from './user/user'
import {createContext, useContext} from 'react'
interface StoreType {
shareStore:ShareStore,
orderStore:OrderStore,
userStore:UserStore
}
const store:StoreType = {
shareStore,
orderStore,
userStore
}
const Context = createContext<Partial<StoreType>>({});
export const StoreProvider:React.FunctionComponent<{}> = ({ children }) => {
return (<Context.Provider value={store}>{children}</Context.Provider>)
};
export const useStore = () => useContext(Context);
复制代码
组件消费:
import {StoreProvider} from './store/index'
<StoreProvider>
<App />
</StoreProvider>
复制代码
最后
感谢阅读,如有任何疑问欢迎留言指教,谢谢!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END