在类组件和函数式组件(react-hook)中使用react-redux

639 阅读1分钟

源码地址:github.com/yuanlijianv…

以加减法为例,效果如下图:

image.png

使用create-react-app构建项目

npx create-react-app my-app
cd my-app
npm start

安装相关包:

npm install @reduxjs/toolkit react-redux --save

项目目录结构如下:

image.png

src/index.js文件

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { Provider } from "react-redux";
import rootStore from "./redux/store";

ReactDOM.render(
  <React.StrictMode>
    <Provider store={rootStore}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);

src/App.js文件

import FunctionComponent from "./components/FunctionComponent";
import { ClassComponent } from "./components/ClassComponent";

function App() {
  return (
    <div>
      <h3>function component</h3>
      <FunctionComponent></FunctionComponent>
      <h3>class component</h3>
      <ClassComponent></ClassComponent>
    </div>
  );
}

export default App;

src/redux文件下创建store.js文件

store.js代码如下:

import { configureStore } from '@reduxjs/toolkit';
import { countSlice } from './functionCount/slice';
import countReducer from "./classCount/countReducer";

export default configureStore({
    reducer: {
        functionCount: countSlice.reducer,
        classCount: countReducer,
    },
})

创建函数式组件store

src/redux/functionCount创建slice.js

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";

const initialState = {
  loading: false,
  error: null,
  number: 0,
};

//异步发送请求
export const signIn = createAsyncThunk("user/signIn", async (paramaters) => {
  const { data } = await axios.post(`http://xxx`, {
    email: paramaters.email,
    password: paramaters.password,
  });
  return data.token;
});

export const countSlice = createSlice({
  name: "count",
  initialState,
  reducers: {
    add: (state) => {
      state.number += 1;
    },
    minus: (state) => {
      state.number -= 1;
    },
  },
  extraReducers: {
    [signIn.pending.type]: (state) => {
      state.loading = true;
    },
    [signIn.fulfilled.type]: (state, action) => {
      state.token = action.payload;
      state.loading = false;
      state.error = null;
    },
    [signIn.rejected.type]: (state, action) => {
      state.loading = false;
      state.error = action.payload;
    },
  },
});

创建类组件store

src/redux/classCount目录下创建countActions.js和countReducer.js

countActions.js

export const ADD_NUMBER = "add_number";
export const MINUS_NUMBER = "minus_number";

export const addActionCreator = () => {
  return {
    type: ADD_NUMBER,
  };
};

export const minusActionCreator = () => {
  return {
    type: MINUS_NUMBER,
  };
};

countReducer.js

import { ADD_NUMBER, MINUS_NUMBER } from "./countActions";

const defaultState = {
  number: 0,
};

export default (state = defaultState, action) => {
  switch (action.type) {
    case ADD_NUMBER:
      return { ...state, number: state.number + 1 };
    case MINUS_NUMBER:
      return { ...state, number: state.number - 1 };
    default:
      return state;
  }
};

src/components目录下分别创建ClassComponent.js文件和FunctionComponent.js文件

ClassComponent.js

import * as React from "react";
import { Component } from "react";
import { connect } from "react-redux";
import {
  addActionCreator,
  minusActionCreator,
} from "../redux/classCount/countActions";

const mapStateToProps = (state) => {
  return {
    number: state.classCount.number,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    add: () => {
      const action = addActionCreator();
      dispatch(action);
    },
    minus: () => {
      const action = minusActionCreator();
      dispatch(action);
    },
  };
};

class CountComponents extends Component {
  render() {
    const { number, add, minus } = this.props;
    return (
      <div>
        <button onClick={add}>+</button>
        <span>{number}</span>
        <button onClick={minus}>-</button>
      </div>
    );
  }
}

export const ClassComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(CountComponents);

FunctionComponent.js

import * as React from "react";
import { useSelector, useDispatch } from "react-redux";
import { countSlice } from "../redux/functionCount/slice";

const FunctionComponent = () => {
    const { number } = useSelector(
        (state) => state.functionCount
    );
    const dispatch = useDispatch();

    const add = () => {
        dispatch(countSlice.actions.add())
    }

    const minus = () => {
        dispatch(countSlice.actions.minus())
    }

    return (
        <div>
            <button onClick={add}>+</button>
            <span>{number}</span>
            <button onClick={minus}>-</button>
        </div>
    );
};
export default FunctionComponent;

老铁,求点赞啊~~