1.前言
用了React
也有两年了,React
也有了很大的变化,在这里就不详细说明了。我记得在之前从调研React
开始,然后使用脚手架搭建了一个React
的项目。好久没搞过框架的搭建了,都是拿来一些优秀的框架直接来做开发。
最近在做React
项目时,需要用到数据共享的模块,便想到需要使用到Redux
去做数据共享。至于原理什么的我就不详细说明了,在官方文档都有说明,而且我相信一定比我写的更详细,所以就不在这里献丑了。
主要是说一下怎么去使用Redux
,以及在实际开发中如何打通数据流。
2. Redux使用
话说休繁,但是还是要提到Redux
的几大要义:
- action
- store
- reducer
- state
2.1创建工作目录
形如上图,我在src目录下创建了一个redux
文件夹,用于存储Redux
的相关模块。
由于在数据的共享中并不指一个模块,所以这里我更希望你将他们分开多不同的文件中
redux->actions->具体模块->index.js (action的主文件)
redux->actions->具体模块->type.js (action的类型文件)
redux-reducer->具体模块->reducer.js(redux的主文件,当然你也可以直接用index.js来代表主文件,看自己爱好)
redux->reducer->index.js(用于将所有模块的reducer文件聚合成一个reducer,以便我们可以引入到store文件中)
redux->store.js(store的生成文件)
2.2 定义action类型
由于每一个模块都可能有自己的不止一个数据数据被其他模块引用或者改变,所以我们要将能够涉及到的数据都分类一下,比如我这里需要有两个action的类型,一个数数据源的切换,一个是统计更新的数据量,设计到掐模块在做了某些操作的时候,统计量会更新,因为这块设计在header头部,所以不会随模块的数据更新而更新,所以需要做到数据共享。
就需要设计这么两个action类型。
在actions/header/type.js
中定义两个类型的常量
const actionTypes = {
PUBLISH_DATA: "PUBLISH_DATA",
DATA_SOURCE: "DATA_SOURCE"
}
export default actionTypes
2.3 定义action事件
在actions/header/index.js
中定义action事件
import actionTypes from './type'
export const changeSource = (value) => ({
type: actionTypes.DATA_SOURCE,
value
})
export const changePublish = (value) => ({
type: actionTypes.PUBLISH_DATA,
value
})
定义reducer
在reducer/header/index.js
定义reducer
import { cloneDeep } from 'lodash'
import actionTypes from '../../actions/header/type'
const defaultState = {
publishNum: 0,
datasource: []
}
export default (state = defaultState, action) => {
if (action.type === actionTypes.PUBLISH_DATA) {
let newState = cloneDeep(state) //深度拷贝state
newState.publishNum = action.value
return newState;
}
if (action.type === actionTypes.DATA_SOURCE) {
let newState = cloneDeep(state) //深度拷贝state
newState.datasource = action.value
return newState;
}
return state
}
2.4 将reducer聚合
在reducer/index.js
中聚合所有的reducer文件
import { combineReducers } from 'redux';
import headerReducer from '../reducer/header'
const appReducer = combineReducers({
headerReducer
});
export default appReducer;
2.5 创建store文件
在redux/store.js中创建一个store.js
import { createStore } from 'redux' // 引入createStore方法
import appReducer from './reducer/index'
const store = createStore(
appReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) // 创建数据存储仓库
export default store // 暴露出去
2.6 在主入口文件app.js中注册store
<ConfigProvider locale={zhCN} store={store}>
<AppRouter />
</ConfigProvider>
2.7 在绑定数据的模块使用store
import React, { useEffect, useState } from 'react';
import { Badge } from "antd"
import { Link } from 'react-router-dom';
import { UploadOutlined } from '@ant-design/icons'
import { getPublishCounts } from 'src/utils/getpublishcount'
import store from 'src/redux/store'
import './style.less'
/**
* 发布审阅的快捷跳转
* @param {*} props
*/
const ReviewFast = (props) => {
const [pubNum, setpubNum] = useState()
useEffect(()=>{
getPublishCounts()
})
const storeChange = () => {
setpubNum(store.getState().headerReducer.publishNum)
}
store.subscribe(storeChange)
return (<div styleName="publish">
<Link to={{ pathname: "/policy-manage/release-review" }}><Badge count={pubNum} >
<UploadOutlined style={{ fontSize: "25px", color: "gray" }} />
</Badge></Link>
</div>)
}
export default ReviewFast
- 使用
store.getState().headerReducer.publishNum
获取你需要的数据。 - 使用
store.subscribe(storeChange)
去订阅你需要的数据(就像一个监听事件,一旦数据redux中state值发生变化,就会实时更新数据)
2.7 发布action
上面提到需要订阅state值的变化,而去修改state值的变化需要通过store.dispatch(changePublish(res.data.list?.length))
去发布一个action,从而改变state中的值
import { ajax } from 'src/commons/ajax';
import store from 'src/redux/store'
import { changePublish } from 'src/redux/actions/header'
/**
* 处理发布订阅数据统计
*/
export const getPublishCounts = () => {
ajax.get("/managewithgroups/api/releasereview/reversion").then(res => {
store.dispatch(changePublish(res.data.list?.length))
})
}
那么在这跟新数据后,在绑定数据的地方通过store.subscribe
就可以订阅变化后的state值。