自定义React全局状态管理工具
前言
最近学习了React框架,在学到Redux全局状态管理库时,觉得很繁琐复杂,于是自己编写了一个状态管理工具类(核心思想:订阅者模式),进行简单的全局状态管理(如果是大型项目且状态复杂,还是建议使用Redux)。废话不多说,直接看下面代码。
项目结构、界面图
代码实现
自定义MCStore类
在项目 mc-store-demo/src/mcStore/index.js 文件中,编写了一个自定义的状态管理类MCStore,代码如下
//自定义状态管理store
class MCStore {
//state保存状态,这里保存了role、passage两个状态
state = {
role: 'user', //权限字段,admin与user
passage: ''
}
//handle保存回调函数
handle = {}
constructor() {
//set 更改state里的状态
this.set = function (stateName, payload) {
this.state[stateName] = payload;
if (this.handle[stateName]) {
this.handle[stateName].forEach(element => {
element.process(payload);
});
}
}
//get 获取state状态
this.get = function (stateName) {
return this.state[stateName];
}
//订阅函数
this.subscribe = function (stateName, callback) {
if (!this.handle[stateName]) {
this.handle[stateName] = []
}
const subscriberId = this.guid();
this.handle[stateName].push({
uid: subscriberId,
process: callback
});
return subscriberId;
}
//取消订阅
this.unSubscribe = function (stateName, subscriberId) {
if (this.handle[stateName]) {
this.handle[stateName] = this.handle[stateName].filter(element => element.uid !== subscriberId);
}
}
}
//生成唯一ID
guid() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0)
.toString(16)
.substring(1);
}
return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}
}
const mcStore = new MCStore(); //生成单实例
export { mcStore }
Home组件中使用mcStore
import React, { Component } from 'react'
import { mcStore } from '../mcStore'
import '../styles/home.scss'
import PassageComp from '../components/Home/PassageComp.js'
export default class Home extends Component {
constructor(props) {
super(props)
this.state = {
role: mcStore.get('role')
}
}
componentDidMount() {
//订阅,当mcStore的State对象中的role属性发生变化,会触发下面的回调函数
this.subscriberRole = mcStore.subscribe('role', (data) => {
this.setState({ role: data });
});
}
componentWillUnmount() {
//取消订阅
mcStore.unSubscribe('role', this.subscriberRole);
}
handlePublish = () => {
const passage = this.mInput.value.trim();
if (passage) {
mcStore.set('passage', passage);
}
}
render() {
const { role } = this.state;
return (
<div>
<h2>Home page</h2>
<div className='permission'>
当前权限:{role === 'admin' ? '管理者' : '普通用户'}
<button onClick={() => { mcStore.set('role', 'admin'); }}>管理者</button>
<button onClick={() => { mcStore.set('role', 'user'); }}>普通用户</button>
</div>
<div>
<input type='text' ref={input => { this.mInput = input }}></input>
<button onClick={this.handlePublish}>发布</button>
<PassageComp />
</div>
</div>
)
}
}