文章目录
功能说明
redux 主要用于管理状态
react-redux 将ui与状态分离
redux-thunk redux可以执行异步操作
核心说明
redux
dispatch(派发器触发actions中的对应方法)=>actions(具体去触发对应的reducer的方法)=>reducer(j具体的修改state中的数据的方法,reducer中的方法要求都是村纯函数)=>subscribe(订阅者,state中的数据变化,就会触发)=>unsubscribe(取消订阅)
react-redux
添加类似拦截的机制,将redux中的数据的方法,都绑定到props上,这样就需要我们制作两个方法,来分别绑定 state和触发actions,与ui层解耦
const mapDispatchToProps = dispatch => ({
// 构造相关方法 来触发actions中的方法
incActionS: function () {
dispatch(incAction())
},
decActionS: function () {
dispatch(decAction())
},
// 这儿用于触发异步的方法,会自动去调用getBanners
getBanners:function () {
dispatch(getBanners)
}
})
export default connect(mapStateToProps, mapDispatchToProps)(memo(Home))
redux-thunk
中间件机制
将actions中的函数直接返回对象,变成了方法,在方法中进行异步处理,并将返回后的数据通过dispatch再次触发actions中的方法,进而修改数据
文件目录
安装依赖
yarn add redux react-redux redux-thunk redux-devtools-extension redux-persist
index.js
import {createStore,applyMiddleware} from 'redux';
import thunkMiddleware from "redux-thunk"
import {composeWithDevTools} from 'redux-devtools-extension'
import reducer from './reducer.js';
// 状态持久化
import {persistStore, persistReducer} from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const persistConfig = {
key: 'root',
storage: storage,
stateReconciler: autoMergeLevel2 // 查看 'Merge Process' 部分的具体情况
};
const myPersistReducer = persistReducer(persistConfig, reducer)
// const compooseEnhancer=window.__REDUX_DEVTOOLS_EXTENSION_COMPOOSE__ || compoose
// 专门用于异步请求的中间件
const storeEnhancer=composeWithDevTools(applyMiddleware(thunkMiddleware))
const store = createStore(myPersistReducer,storeEnhancer);
export const persistor = persistStore(store)
export default store;
state.js
export default {
count : 0
}
constants.js
const INCREMENT="increment"
const DECREMENT="decrement"
export {
INCREMENT,
DECREMENT
}
actionCreators.js
import {
INCREMENT,
DECREMENT
} from "./constant"
export const incrementAction= data =>({
type:INCREMENT,
data
})
export const decrementAction= data =>({
type:DECREMENT,
data
})
export const incrementActionAsync= data =>{
return dispatch=>{
setTimeout(()=>{
dispatch(incrementAction(data))
},1000)
}
}
reducer.js
import {
ADD_NUMBER,
SUB_NUMBER,
INCREMENT,
DECREMENT,
BANNERS,
SET_USERDATA
} from './constants.js';
import defaultState from './state'
// reducer 实际修改数据的地方
function reducer(state = defaultState, action) {
switch (action.type) {
case ADD_NUMBER:
return { ...state, counter: state.counter + action.num };
case SUB_NUMBER:
return { ...state, counter: state.counter - action.num };
case INCREMENT:
return { ...state, counter: state.counter + 1 };
case DECREMENT:
return { ...state, counter: state.counter - 1 };
case BANNERS:
return { ...state, banners: action.banners };
case SET_USERDATA:
return { ...state, userdata: action.userdata };
default:
return state;
}
}
export default reducer;
页面
index.js
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from "react-redux"
// 导入路由 BrowserRouter(history) HashRouter(hash)
import { HashRouter } from "react-router-dom";
import App from './App';
import 'antd/dist/antd.css';
import './assets/css/index.scss';
import "./mock/index"
import store from "./store"
import {persistor} from './store'
import {PersistGate} from 'redux-persist/lib/integration/react';
import Loading from "comp/common/Loading"
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<HashRouter>
<Suspense fallback={<Loading></Loading>}>
<App />
</Suspense>
</HashRouter>
</PersistGate>
</Provider>,
document.getElementById('root')
);
实际jsx页面
import React, { memo } from 'react'
import { useSelector, shallowEqual, useDispatch} from "react-redux" // 注意
import { incrementAction, decrementAction, incrementActionAsync } from "./store/actions"
function App() {
const { count } = useSelector(state => ({
count: state.count.count
}), shallowEqual)
const dispatch=useDispatch()
return (
<div>
<h2>
{count}
</h2>
<button onClick={() => {
dispatch(incrementAction(1))
}}>
+1
</button>
<hr />
<button onClick={() => {
dispatch(decrementAction(5))
}}>
-5
</button>
<hr />
<button onClick={() => {
dispatch(incrementActionAsync(5))
}}>
异步+5
</button>
</div>
)
}
export default memo(App)