React+redux 函数式组件中使用

412 阅读3分钟

一:准备工作,创建redux所需要的文件

 scr下变创建文件夹下创建一个 redux 文件夹
 redux 文件夹下创建 actions 文件夹、reducers 文件夹、constants.ts 文件、store.ts 文件
 reducers 文件夹下创建 index.ts 文件
 
 **文件层级:**
 - src 
     - redux 
     - actions 
     - reducers - index.ts 
     - constans.ts 
     - store.ts
  • actions 文件夹:
    用于为组件生成 action 对象。
  • reducers 文件夹:
    (1)用于创建一个组件服务的 reducer,reducer 的本质是一个函数。
    (2)reducer 函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)。
  • reducers/index.ts 文件:
    该文件用于汇总所有的 reducer 为一个总的 reducer 。
  • constans.ts 文件:
    (1)用于定义 action 对象中 type 类型的常量值。
    (2)目的只有一个:便于管理的同时防止程序员单词写错。
  • store.ts 文件:
    该文件专门用于暴露一个 store 对象,整个应用只有一个store 对象。

二: 安装 redux 所需的依赖 基础配置

  1. 安装 redux
    用于创建redux中最为核心的store对象
    yarn add redux react-redux
  2. 安装 redux-thunk
    用于支持异步 action
    yarn add redux-thunk
  3. 安装 redux-devtools-extension
    用于支持 react-redux 开发者工具的使用
    yarn add redux-devtools-extension
  • src/redux/reducers/index.ts 文件修改

    // 引入combineReducers,用于汇总所有的reducer
    import { combineReducers } from "redux";
    // 汇总所有的reducer,变为一个整的reducer
    const allReducer = combineReducers({
        // 接收 reducer
    });
    export default allReducer;
    
  • src/redux/store.ts 文件修改

    // 引入createStore,专门用于创建redux中最为核心的store对象
    import { createStore, applyMiddleware } from "redux";
    // 引入redux-thunk,用于支持异步action
    import thunk from "redux-thunk";
    // 引入 redux-devtools-extension
    import { composeWithDevTools } from "redux-devtools-extension";
    // 引入汇总之后的reducer
    import allReducer from "./reducers";
    
    const store = createStore(
      allReducer,
      composeWithDevTools(applyMiddleware(thunk))
    );
    export default store;
    
  • src/main.ts

    import React from 'react'
    import ReactDOM from 'react-dom/client'
    import App from './App';
    import './index.scss;
    import { BrowserRouter } from 'react-router-dom';
    
    import { Provider } from "react-redux"; //引入redux
    import store from "./redux/store"; //引入redux
    // 用 Provider 包裹 App,目的是让 App 所有的后代容器组件都能接收到store
    
    ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
      <React.StrictMode>
        <Provider store={store}>
            <App/>
        </Provider>
      </React.StrictMode>,
    )
    
    

三: 配置组件功能

一函数式组件写法 Count
  1. src/redux/constants.ts 文件修改,添加方法常量

    // 定义action对象中type类型的常量值
    export const INCREMENT = "increment";
    export const DECREMENT = "decrement";
    
  2. src/redux/actions 文件夹新增 count.ts

    import { INCREMENT, DECREMENT } from "../constants.ts";
    // 定义方法
    // 简写方式
    // export const increment = (data) => ({ type: INCREMENT, data });
    // 正常方式
    export const increment = (data:any) => {
      return {
        type: INCREMENT,
        data,
      };
    };
    // 减
    export const decrement = (data:any) => {
      return {
        type: DECREMENT,
        data,
      };
    };
    
  3. src/redux/reducers 文件夹新增 count.ts,对应 actions 文件中 的 count.ts

    /**
     * 1. 该文件是用于创建一个为为Count组件服务的reducer,reducer的本质是一个函数
     * 2. reducer函数会接收到两个参数,分别为:之前的状态(preState),动作对象(action)
     */
    import { DECREMENT, INCREMENT } from "../constants.js";
    
    // const initState = 3; //初始化状态
    const INITIAL_STATE = {
        name:'名字',
        num:1,
    }
    
    // 当第一次 preState 为 undefined 时,preState 赋值等于 initState
    export default function increment(preState = INITIAL_STATE, action:any) {
        console.log('191991:',preState,action)
      // 从 action 对象中获取:type,data
      const { type, data } = action;
      // 根据 type 决定加工数据
      switch (type) {
        case INCREMENT:
        return {
            ...preState,
            num: preState.num + data['num'],
            name: data['name'],
        }
        case DECREMENT:
          return {
            ...preState,
            num: preState.num - 1,
            name: '名字',
        }
        default:
          return preState; // 返回preState src/redux/reducers/index.ts allReducer 接收这个值
      }
    };
    
  4. src/redux/reducers/index.ts 文件修改,添加合并 Count 组件 返回值

     // 引入combineReducers,用于汇总所有的reducer
     import { combineReducers } from "redux";
     import count from './count'
     // 汇总所有的reducer,变为一个整的reducer
     const allReducer = combineReducers({
         // count:count,
         count,
     });
     export default allReducer;
    

四:如何使用

import React, { useState, useEffect } from 'react';
import './index.scss'

import { useDispatch,useSelector } from 'react-redux' // 引入react-redux 使用
import { increment,decrement } from '../../redux/actions/count' // 引入count组件中的方法

export default function Demo() {
  // 函数式redux使用
  const dispatch = useDispatch();
  const newState: any = useSelector((state) => state);

    return(
        <div>
            {newState.count['name']}
            <button onClick={()=>dispatch(increment({num:1,name:'名字加'}))}>加加加</button>
            {newState.count['num']}
            <button onClick={()=>dispatch(decrement(1))}>减减减</button>
        </div>
    )
}

案例:

image.png