redux、react-redux、redux-thunk 实现
2023-10-17 本文已影响0人
暴躁程序员
1. 安装依赖库
npm i redux react-redux redux-thunk -S
2. 在程序 index.js 入口文件中,导入 store,使用 Provider 组件包裹根组件
被 Provider 包裹的组件,都可以获取和操作 store 状态
import React from "react";
import { BrowserRouter } from "react-router-dom";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux"; // 1. 导入 Provider 组件
import store from "./store"; // 2. 导入 store
const root = ReactDOM.createRoot(document.getElementById("root"));
// 3. 使用 Provider 包裹组件
root.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
3. 定义 store,创建 src\store\index.js
import { createStore, compose, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk'; // 1. 导入 redux-thunk 异步中间件
import reducer from "../pages/home/store/reducer" // 2. 导入组件 reducer
// 3,合并各组件 reducer
const rootReducer = combineReducers({
home: reducer,
});
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk)
));
export default store;
4. 在组件中获取和操作 store 状态
- 定义 action 的 type,创建 src\pages\home\store\constants.js
export const CHANGE_NUM_SYNC = 'home/CHANGE_NUM_SYNC';
export const CHANGE_NUM_ASYNC = 'home/CHANGE_NUM_ASYNC';
- 定义组件 reducer,创建 src\pages\home\store\reducer.js
// 1. 导入 action 的 type
import { CHANGE_NUM_SYNC,CHANGE_NUM_ASYNC } from "./constants";
// 2. 定义 store 初始状态
const defaultState = {
num: 1,
};
// 3. 创建 reducer,在 dispatch action 后触发,不改变 store 状态的情况下,结合原始 store 状态和 action 返回最新 store 状态
const reducer = (state = defaultState, action) => {
switch (action.type) {
case CHANGE_NUM_SYNC:
return Object.assign({}, state, {
num: state.num + action.payload,
});
case CHANGE_NUM_ASYNC:
return Object.assign({}, state, {
num: state.num + action.payload,
});
default:
return state;
}
};
export default reducer;
- 定义组件 action,创建 src\pages\home\store\actionCreators.js
// 1. 导入 action 的 type
import { CHANGE_NUM_SYNC, CHANGE_NUM_ASYNC } from "./constants";
// 2. 定义同步 action
export const changeNumActionSync = (num, ownProps) => {
return {
type: CHANGE_NUM_SYNC,
payload: num + ownProps.componentParam,
};
};
// 3. 定义异步 action
export const changeNumActionAsync = (num, ownProps) => {
return (dispatch) => {
setTimeout(() => {
dispatch({
type: CHANGE_NUM_ASYNC,
payload: num + ownProps.componentParam,
})
}, 1000);
};
};
- 定义组件,创建 src\pages\home\index.js
import React, { PureComponent } from "react";
import { connect } from 'react-redux'; // 1. 导入 connect 用户连接 store 和 组件
import {changeNumActionSync, changeNumActionAsync} from "./store/actionCreators" // 2. 导入 action
class Home extends PureComponent {
render() {
console.log(this.props);
return (
<>
<h1> react-redux </h1>
<div> { this.props.num } </div> {/* 6. 在 rendeer 函数中使用store状态映射 */}
<button onClick={()=> this.props.changeNumSync(100)}>num ++ 同步</button>
<button onClick={()=> this.props.changeNumAsync(10000)}>num ++ 异步</button> {/* 7. 在 rendeer 函数中使用方法映射 */}
</>
);
}
}
// 3. store 状态映射,state 参数为 store 状态,ownProps 参数为父组件传递过来的状态
const mapStateToProps = (state, ownProps) => {
return {
num: state.home.num + ownProps.componentParam,
}
}
// 4. store 方法映射,dispatch 参数为 store.dispatch 方法,ownProps参数为父组件传递过来的状态
const mapDispatchToProps = (dispatch, ownProps) => {
return {
changeNumSync: (num) => {
dispatch(changeNumActionSync(num,ownProps))
},
changeNumAsync: (num) => {
dispatch(changeNumActionAsync(num,ownProps))
},
}
}
// 5. 通过 connect(mapStateToProps, mapDispatchToProps)(component) 连接组件
export default connect(mapStateToProps, mapDispatchToProps)(Home)