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 下载项目

相关推荐
清灵xmf1 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨1 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL1 小时前
npm入门教程1:npm简介
前端·npm·node.js
小白白一枚1112 小时前
css实现div被图片撑开
前端·css
薛一半2 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js
@蒙面大虾2 小时前
CSS综合练习——懒羊羊网页设计
前端·css
MarcoPage3 小时前
第十九课 Vue组件中的方法
前端·javascript·vue.js
.net开发3 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
**之火3 小时前
Web Components 是什么
前端·web components
顾菁寒3 小时前
WEB第二次作业
前端·css·html