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 状态

  1. 定义 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';
  1. 定义组件 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;
  1. 定义组件 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);
  };
};
  1. 定义组件,创建 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)
上一篇下一篇

猜你喜欢

热点阅读