由于平时工作中使用
vue
比较多,故而在全局状态管理上必然离不开vuex
这个依赖库,使用起来尤为顺手。最近在搭建公司前端的配置中心时,考虑到维护性和可扩展性的需求,想使用typescript
作为基础,权衡之下选择了对typescript
支持更友好的react
作为基础框架,那么除了mobx
之外,也尝试了redux
,虽说和vuex
的原理差不多,但是用起来却十分繁琐,于是看了一下其他大佬的文章,发现结合react
的hook
是可以自己创建一个轻量级的’redux’来管理一些比较顶层的状态。
一、技术准备
要模仿redux的store,其实依赖了react的context api,由于react的一下props经常面临多层透传的情况,导致维护性不高,于是官方提供了context的上下文api,让所有子组件共享全局的状态。
因此,要完成这个“轻量版”的redux,需要提前了解一下的知识点:
不熟练的小伙伴,建议点击以上传送门提前熟悉了解一下API的用法,对于已经理解并且使用了一段时间的小伙伴,相信下面的内容也不用看了,凭着自己的理解与思考其实很容易就能写出一个非常轻量的‘redux’
二、模拟Provider组件
在redux的使用中,store的数据很巧妙地用了组件的属性透传下去组件树里,像这样:
import { Provider } from 'react-redux';
import store from './store';
import App from './App.jsx';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
因此,我们也可以手动制作一个Provider组件出来进行store的透传:
在项目的根目录下创建一个Provider.js文件:
import React,{Component} from 'react';
export const storeContext = React.createContext();
export default class Provider extends Component{
render(){
return (
<storeContext.Provider value={this.props.store}>
{this.props.children}
</storeContext.Provider>
)
}
}
三、模拟reducer
redux是通过接收aciton执行对应的reducer来更新数据的,因此我们需要用到一个React hook来模拟reducer的行为,恰好React提供了useReducer的API可以方便我们在局部组件里方便地管理数据。因此,为了模拟出redux的效果,我们需要从“局部”变为“全局”。
首先,我们把reducer的逻辑先解耦成单独的文件方便维护,在自定义的目录下建一个Reducer.js:
export const initialState = {
date:'2月11日'
count:0
}
export const reducer = (state, action)=>{
switch (action.type) {
case 'TEST':
return {...initialState,count:count+1}
default:
return initialState;
}
}
随后,我们在App.jsx中,开始模拟redux:
import React,{useReducer} from 'react';
import Provider from './Provider';
import Child from './views/child';
import {initialState,reducer} from './Reducer';
import './App.css';
function App() {
const [state,dispatch] = useReducer(reducer,initialState);
return (
<div className="App">
<Provider store={{state,dispatch}}>
<Child/>
</Provider>
</div>
);
}
export default App;
至此,我们已经成功完成了一个轻量极地redux组件了,至于怎么使用,并且它和真实redux的利弊,将在下一篇中分享;