React(react18)中组件通信06——redux-toolkit + react-redux

React(react18)中组件通信06------redux-toolkit + react-redux

    • [1 前言](#1 前言)
    • [1.1 redux 和 react-redux](#1.1 redux 和 react-redux)
    • [1.2 关于redux-toolkit](#1.2 关于redux-toolkit)
      • [1.2.1 官网](#1.2.1 官网)
      • [1.2.2 为什么要用Redux Toolkit?](#1.2.2 为什么要用Redux Toolkit?)
    • [1.3 安装 Redux Toolkit](#1.3 安装 Redux Toolkit)
    • [1.4 Redux Toolkit相关API](#1.4 Redux Toolkit相关API)
  • [2. 开始例子------官网例子](#2. 开始例子——官网例子)
    • [2.1 创建 Redux Store](#2.1 创建 Redux Store)
    • [2.2 为 React 提供 Redux Store](#2.2 为 React 提供 Redux Store)
    • [2.3 创建 Redux State Slice](#2.3 创建 Redux State Slice)
      • [2.3.1 counterSlice.js文件](#2.3.1 counterSlice.js文件)
      • [2.3.2 对比之前的action 和 reducer](#2.3.2 对比之前的action 和 reducer)
    • [2.4 添加 Slice Reducers 到 Store](#2.4 添加 Slice Reducers 到 Store)
    • [2.5 在 React 组件中使用 Redux State 和 Actions](#2.5 在 React 组件中使用 Redux State 和 Actions)
    • [2.6 渲染](#2.6 渲染)
    • [2.7 效果](#2.7 效果)
      • [2.7.1 效果展示](#2.7.1 效果展示)
      • [2.7.2 说明](#2.7.2 说明)
    • [2.8 注意:](#2.8 注意:)
    • [2.9 附代码](#2.9 附代码)
  • [3. 例子2------练手小例子](#3. 例子2——练手小例子)
    • [3.1 再添加一个Dog组件](#3.1 再添加一个Dog组件)
    • [3.1.1 编写 dogSlice](#3.1.1 编写 dogSlice)
      • [3.1.2 修改store.js](#3.1.2 修改store.js)
      • [3.1.3 编写dog组件](#3.1.3 编写dog组件)
      • [3.1.4 效果](#3.1.4 效果)
    • [3.2 这数据共享也太简单了吧](#3.2 这数据共享也太简单了吧)
      • [3.2.1 试试数据共享](#3.2.1 试试数据共享)
      • [3.2.2 react-redux + redux 数据共享](#3.2.2 react-redux + redux 数据共享)
  • [4. 关于 Payload------载荷payload](#4. 关于 Payload——载荷payload)
  • [5. 项目代码](#5. 项目代码)
    • [5.1 代码目录](#5.1 代码目录)
    • [5.2 下载项目](#5.2 下载项目)

1 前言

1.1 redux 和 react-redux

1.2 关于redux-toolkit

1.2.1 官网

1.2.2 为什么要用Redux Toolkit?

  • 首先看官网怎么说?
  • 然后看我们代码中createStore已经被弃用了,如下:

1.3 安装 Redux Toolkit

  • 安装命令如下

    javascript 复制代码
    npm install @reduxjs/toolkit
    
    yarn add @reduxjs/toolkit
  • 如果项目没有装过react-redux,可以两个一起安装,但是不用单独安装 redux 了,react-redux + redux-toolkit 替换了 react-redux + redux

    bash 复制代码
    npm install @reduxjs/toolkit react-redux
    
    yarn add @reduxjs/toolkit react-redux

1.4 Redux Toolkit相关API

  • 先简单介绍几个

  • 官网全,还是看官网吧

2. 开始例子------官网例子

2.1 创建 Redux Store

  • 从 Redux Toolkit 中导入 configureStore API。我们将开始创建一个空的 Redux store,并导出它,如下:

    javascript 复制代码
    import { configureStore } from '@reduxjs/toolkit';
    
    export default configureStore({
      reducer: {
         
      },
    });
  • 这将创建一个 Redux store,并自动配置 Redux DevTools 扩展,以便你可以在开发时检查 store。

2.2 为 React 提供 Redux Store

  • 这个按照原先的保持不变就行,如下:

2.3 创建 Redux State Slice

2.3.1 counterSlice.js文件

  • 创建 slice 需要一个字符串名称来标识 slice,一个初始 state 值,以及一个或多个 reducer 函数来定义如何更新 state。创建 slice 后,我们可以导出生成的 Redux action creators 和整个 slice reducer 函数。
  • 如下:

2.3.2 对比之前的action 和 reducer

  • 之前的action写法,如下:

    javascript 复制代码
    function incrementOne(){
        type:'INCREMENT_ONE'
    }
    function incrementNumber(number){
        type:'INCREMENT_NUMBER',
        number:number
    }
    export default{incrementOne,incrementNumber}
  • 之前的reducer写法,如下

    javascript 复制代码
     function countReducer(state = 0,action){
         switch (action.type) {
             case 'INCREMENT_ONE':
                 return state + 1;
             case 'INCREMENT_NUMBER':
                 return state + action.number;
             default:
                 return state;
         }
     }
     export default{countReducer}

2.4 添加 Slice Reducers 到 Store

  • 接下来,我们需要从 counter slice 中导入 reducer 函数并将其添加到我们的 store 中。通过在 reducers 参数中定义一个字段,我们告诉 store 使用这个 slice reducer 函数来处理该 state 的所有更新。
  • 所以最后的store.js,如下:

2.5 在 React 组件中使用 Redux State 和 Actions

  • 现在我们可以使用 React Redux hooks 让 React 组件与 Redux store 交互。我们可以使用 useSelector从 store 中读取数据(不通过props了),并使用 useDispatch dispatch actions。
  • 组件内设计如下:

2.6 渲染

  • 一样的代码

2.7 效果

2.7.1 效果展示

  • 如下:

2.7.2 说明

  • 单击 【点我+1】 、 【点我-1】和【加数】按钮:
    对应的 Redux action 会被 dispatch 到 store;
    计数 slice reducer 将看到 actions 更新其 state;
    <Counter> 组件将从 store 中看到新的 state 值,并使用新的数据重新渲染自己。

2.8 注意:

  • 如下:

2.9 附代码

  • counterSlice.js

    javascript 复制代码
    import {createSlice} from '@reduxjs/toolkit'
    
    export const counterSlice = createSlice({
        name: 'myFirstCounterSlice',  //这个名字随便取  标识
        initialState: {
            value: 0,  //初始值
        },
        reducers: {  // 对比之前的reducer是一个函数,里面是根据不同的action的type判断的switch语句
            incrementOne: (state) =>{  //下面生成 加 1 的action,等价于原先只有type的action
                state.value += 1;
            },
            decrementOne: (state) =>{  //下面生成 减 1 的action,等价于原先只有type的action
                state.value -= 1;
            },incrementNumber: (state,action) =>{  //等价于不只有type一个参数的action
                state.value += action.payload;  //payload
            }
        }
    });
    
    // 为每个 case reducer 函数生成 Action creators
    export const {incrementOne,decrementOne,incrementNumber} = counterSlice.actions;
    
    const countReducer = counterSlice.reducer;
    export default countReducer;
  • store.js

    javascript 复制代码
    import { configureStore } from '@reduxjs/toolkit';
    import countReducer from './reducerAndAction/counterSlice';
    
    export default configureStore({
      reducer: {
         counterState: countReducer,
      },
    });
  • Counter.jsx

    javascript 复制代码
    import {useRef} from "react";
    import { useDispatch, useSelector } from 'react-redux'
    import {incrementOne,decrementOne,incrementNumber} from '../redux/reducerAndAction/counterSlice'
    
    
    function Couter(){
        // console.log(props);
        const numberRef = useRef();
    
        const count = useSelector((state)=>state.counterState.value);
        const dispatch = useDispatch();
    
        //加 1 的
        function addOne(){
            dispatch(incrementOne());
        }
    
        //动态增加
        function addNumber(){
            const stringNumber = numberRef.current.value; //直接取取的是字符串
            const number = parseInt(stringNumber);
            const addNumberAction = incrementNumber(number);   //有参数的action
            dispatch(addNumberAction);
        }
    
        return(
            <div>
                当前数值是:{count}  <br />
                <button onClick={addOne}>点我+1</button>  &nbsp;&nbsp;
    
                <button onClick={()=>dispatch(decrementOne())}>点我-1</button>
    
                <br /><br />
                <input type="number" ref={numberRef} placeholder="请输入要加的数"/>  &nbsp;&nbsp;
                <button onClick={addNumber}>加数</button>
            </div>
        )
    }
    
    export default Couter;

3. 例子2------练手小例子

3.1 再添加一个Dog组件

3.1.1 编写 dogSlice

  • 如下:

3.1.2 修改store.js

  • 如下:

3.1.3 编写dog组件

  • 为了方便,添加就简单写了,需要的自行优化,如下:

3.1.4 效果

  • 如下:

3.2 这数据共享也太简单了吧

3.2.1 试试数据共享

  • 直接访问试试,代码如下:
  • 还真行,这可比redux + react-redux 简单太多了,效果如下

3.2.2 react-redux + redux 数据共享

4. 关于 Payload------载荷payload

  • 关于state.value += action.payload; //payload ,下面举个例子,如果还用原先的redux的话,action也可以如下写法:

  • 再比如, "新增一个待办事项" 的 Action创造函数,你可以这么写:

    javascript 复制代码
    var id = 1
    function addTodo(content) {
      return {
        type: 'ADD_TODO',
        payload: {
          id: id++,
          content: content, // 待办事项内容
          completed: false  // 是否完成的标识
        }
      }
    }
  • 这就可以理解 action.payload 为啥要这么用,为了规范呗,不管你传的是什么参数,数字还是对象,都是action.payload,看一下我们上面的例子就更好理解了,如下:

5. 项目代码

5.1 代码目录

  • 如下:

5.2 下载项目

相关推荐
热爱编程的小曾8 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin20 分钟前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox33 分钟前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞2 小时前
Firefox默认在新标签页打开收藏栏链接
前端·firefox
高达可以过山车不行2 小时前
Firefox账号同步书签不一致(火狐浏览器书签同步不一致)
前端·firefox
m0_593758102 小时前
firefox 136.0.4版本离线安装MarkDown插件
前端·firefox