功能说明
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 => ({
incActionS: function () {
dispatch(incAction())
},
decActionS: function () {
dispatch(decAction())
},
getBanners:function () {
dispatch(getBanners)
}
})
export default connect(mapStateToProps, mapDispatchToProps)(memo(Home))
redux-thunk
中间件机制 将actions中的函数直接返回对象,变成了方法,在方法中进行异步处理,并将返回后的数据通过dispatch再次触发actions中的方法,进而修改数据
文件目录
stores下新建如下目录
index.js
import {createStore,applyMiddleware} from 'redux';
import thunkMiddleware from "redux-thunk"
import reducer from './reducer.js';
const storeEnhancer= applyMiddleware(thunkMiddleware)
const store = createStore(reducer,storeEnhancer);
export default store;
state.js
export default {
counter: 0,
banners:[]
}
constants.js
export const ADD_NUMBER = "ADD_NUMBER";
export const SUB_NUMBER = "SUB_NUMBER";
export const INCREMENT = "INCREMENT";
export const DECREMENT = "DECREMENT";
export const BANNERS = "BANNERS";
actionCreators.js
import {
ADD_NUMBER,
SUB_NUMBER,
INCREMENT,
DECREMENT,
BANNERS
} from './constants.js';
import axios from "axios"
export const addAction = num => ({
type: ADD_NUMBER,
num
});
export const subAction = num => ({
type: SUB_NUMBER,
num
});
export const incAction = () => ({
type: INCREMENT
});
export const decAction = () => ({
type: DECREMENT
});
export const getBannersAction = (banners) => ({
type: BANNERS,
banners
});
export const getBanners=(dispatch)=>{
axios.get("/http/list").then(res=>{
dispatch(getBannersAction(res.data))
})
}
reducer.js
import {
ADD_NUMBER,
SUB_NUMBER,
INCREMENT,
DECREMENT,
BANNERS
} from './constants.js';
import defaultState from './state'
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 };
default:
return state;
}
}
export default reducer;
页面
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "./mock/index"
import 'antd/dist/antd.less';
import './assets/css/index.scss';
import store from "./store"
import {Provider} from "react-redux"
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
实际jsx页面
import { memo, useEffect } from "react";
import { useDispatch, useSelector, shallowEqual } from "react-redux"
import * as echarts from "echarts"
import { getStructure } from '@/store/actionCreators'
export default memo(function Home(props) {
const { structures } = useSelector(state => ({
structures: state.structures
}), shallowEqual)
const dispatch = useDispatch()
useEffect(async () => {
dispatch(getStructure)
init()
}, [dispatch])
function init() {}
return (
<div className="echarts">
</div>
)
})
|