接下来会以一个数字加减的案例对使用React-redux做一个使用说明
安装库
安装redux库,react-redux库,redux-thunk库
yarn add redux
yarn add react-redux
yarn add redux-thunk
Redux
定义:redux是一个专门用于做状态管理的JS库(不是react插件库)
核心是store和reducers
store.js 创建store对象
我们推荐在src文件夹下建一个redux文件夹,用以存所有的redux状态
src/redux/store.js
// 该文件专门用于暴露一个store对象,整个应用只有一个store对象
// 引入createStore,专门用于创建redux中最为核心的store对象
import { createStore, applyMiddleware } from "redux";
// 引入redux-thunk,用于支持异步action
import thunk from "redux-thunk";
// 导入合并后的reducer
import allReducer from "./reducer";
// 暴露store
export default createStore(allReducer, applyMiddleware(thunk));
Reducer加工数据
我们推荐在redux文件夹下建立一个reducer文件夹,用于统一管理所有的reducer,并且合并回后导入到store文件里
src/redux/reducer/count.js
import { INCREMENT, DECREMENT } from "../constant";
const initState = 0;
export default function countReducer(preState = initState, action) {
const { type, data } = action;
switch (type) {
case INCREMENT:
return preState + data;
case DECREMENT:
return preState - data;
default:
return preState;
}
}
src/redux/reducer/index.js
合并所有reducer
import { combineReducers } from "redux";
// 引入为count组件服务的reducer
import count from "./count_reducer";
export default combineReducers({ count });
Action
创建action对象
src/redux/action/count.js
import { INCREMENT, DECREMENT } from "../constant";
export const increment = (data) => ({ type: INCREMENT, data });
export const decrement = (data) => ({ type: DECREMENT, data });
export const incrementAction = (data, time) => {
return (dispatch) => {
setTimeout(() => {
dispatch(increment(data));
}, time);
};
};
其他
统一管理常量
我们推荐在redux文件夹下建立一个constant的js文件,用于统一管理所有的store里的常量
例如:src/redux/constant.js
/* 该模块是用于定义action对象中type类型的常量值 */
export const INCREMENT = "increment";
export const DECREMENT = "decrement";
React-Redux
我们一般建议
components文件夹放的都是UI组件
containers文件夹下放的都是容器组件
容器组件操作。 containers/Count/index.jsx
映射状态 mapstateToProps
映射操作状态的方法 mapDispatchToProps
注意:我们注册路由表的时候,引入的是容器组件,不是UI组件
// 引入Count的UI组件
import CountUI from "../../components/Count";
//引入connect用于连接UI组件与redux
import { connect } from "react-redux";
import {
increment,
decrement,
incrementAction,
} from "../../../../redux/action/count";
// function mapStateToProps(state) {
// return { count: state };
// }
// function mapDispatchToProps(dispatch) {
// return {
// add: (number) => dispatch(increment(number)),
// reduce: (number) => dispatch(decrement(number)),
// addAsyc: (number, time) => dispatch(incrementAction(number, time)),
// };
// }
// 使用connect()()创建并暴露一个Count的容器组件I
// export default connect(mapStateToProps, mapDispatchToProps)(CountUI);
export default connect((state) => ({ count: state.count }), {
increment,
decrement,
incrementAction,
})(CountUI);
UI组件 components/Count/index.jsx
import React, { Fragment, useRef } from "react";
export default function Count(props) {
// 获取选择框ref实例
const selectNum = useRef();
//加
const increment = () => {
const {
current: { value },
} = selectNum;
props.increment(value * 1);
};
//减
const decrement = () => {
const {
current: { value },
} = selectNum;
props.decrement(value * 1);
};
//奇数加
const incrementIfOdd = () => {
const {
current: { value },
} = selectNum;
if (props.count % 2 !== 0) {
props.increment(value * 1);
}
};
//异步加
const incrementAsyc = () => {
const {
current: { value },
} = selectNum;
props.incrementAsyc(value * 1, 500);
};
return (
<Fragment>
<h1>当前求和为:{props.count}</h1>
<select ref={selectNum}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={incrementIfOdd}>当前求和为奇数再加</button>
<button onClick={incrementAsyc}>异步加</button>
</Fragment>
);
}
全局传store
provide 不需要额外单次的传store到组件里
全局传store,会根据需求,传store到需要的组件里
src/index.jsx
安装Redux DevTools
外网安装Redux DevTools
安装redux开发者工具搭配的库
yarn add redux-devtools-extension
store里引入redux-devtools-extension