RTK(二代redux)和一代redux的对比学习

说明

RTK是在原有的redux基础上进行了二次封装,提供开箱即用的API,所以更像是他的一个类库。

对比来理解,他们俩一个像是js,另一个则像是jQuery。所以为什么不使用jQuery(RTK)来开发,上手简单。

Tips:对比redux学习是为了更好的理解RTK是怎么对redux进行封装的。

1,安装核心依赖包

redux

安装:npm install redux

// 依赖包示例:"redux": "2.3"

RTK

安装:npm install @reduxjs/toolkit

// 依赖包实例:"@reduxjs/toolkit": "^1.9.7"

2,定义状态和reducer函数

redux

分别定义state状态和reducer函数,reducer函数接收当前的state和action对象。

// 定义初始状态
const initialState = {count: 0,
};// 编写reducer函数
function counterReducer(state = initialState, action) {switch (action.type) {case 'incremented':return { value: state.count + 1 }case 'decremented':return { value: state.count - 1 }default:return state}
}

RTK

利用createSlice切片来简化action和reducer的创建,在createSlice中定义reducers对象,每个键值对代表一个action类型和对应的reducer函数。

一个createSlice切片可以理解为一个业务模块。

// 引入创建slice切片的函数
import { createSlice } from '@reduxjs/toolkit';// 创建一个切片,传入name、初始值、reducers函数
// createSlice是对createAction和createReducer的包装和更高层的抽象
const counterSlice = createSlice({name: 'counter',initialState: { count: 0 },reducers: {increment(state) {state.count += 1;},decrement(state) {state.count -= 1;},},
});

3,创建store

redux

使用createStore函数。这个函数接受一个reducer函数作为参数,并返回一个新的Store对象。

// 引入创建store的函数
import { createStore } from 'redux'// 用reducer作为参数创建store
let store = createStore(counterReducer)

RTK

使用configureStore函数替代createStore,将创建的切片对象的reducer属性作为参数传入,RTK 自动处理 Reducer 的合并。

// 引入创建store的函数
import { configureStore } from '@reduxjs/toolkit'// 通过将切片.reducer函数作为参数,创建store
const store = configureStore({reducer: counterSlice.reducer
})

4,dispatch派发action和subscribe订阅

redux

订阅:通过store.subscribe方法来实现订阅。

分发:通过store.dispatch方法来实现分发,传入action

// store通过subscribe订阅
store.subscribe(() => console.log(store.getState()))// 调用store的dispatch方法改变state
store.dispatch({ type: 'increment' })
// {count: 1}
store.dispatch({ type: 'decrement' })
// {count: 1}

RTK: 

订阅:也是通过store.subscribe方法来实现订阅。

分发:通过store.dispatch方法来实现分发,他传入的action通过切片对象的actions属性来解构获取

// store通过subscribe订阅
store.subscribe(() => console.log(store.getState()))// 通过创建的切片counterSlice.actions解构获得各个reducer函数
export const { increment, decrement } = counterSlice.actions;// 调用store的dispatch方法改变state
store.dispatch(increment())
// {count: 1}
store.dispatch(decrement ())
// {count: 1}

5,创建 Selectors

Selectors 是函数,用于从 state 中选择数据。

RTK提供了createSelector函数,用于创建可缓存的selectors,以提高性能。

createSelector函数提供了 memoization 功能,这意味着如果传入的参数没有变化,它会返回缓存的结果,而不是重新计算。

使用selectors可以轻松地从state中获取数据,而无需担心如何正确地引用和更新 state。

redux

手动编写选择器函数。

// Redux 选择器函数
function selectCount(state) {return state.count;
}const currentValue = selectCount(store.getState());

RTK

使用createSelector函数创建一个 selector函数,该函数接收 state 作为参数,并返回所需的数据片段。

// RTK 选择器函数,counter是切片的name
export const selectCount = (state) => state.counter.count;

6,使用trunk分发异步action

redux

需要引入redux-trunk中间件,然后手动编写async/await逻辑处理异步操作,并且手动派发三种不同的 action 来表示异步操作的不同阶段:开始pending、成功fulfilled和失败rejected

// 定义action creators
export const fetchDataBegin = () => ({type: 'FETCH_DATA_BEGIN',
});export const fetchDataSuccess = (data) => ({type: 'FETCH_DATA_SUCCESS',payload: data,
});export const fetchDataFailure = (error) => ({type: 'FETCH_DATA_FAILURE',payload: error,
});// redux-thunk进行异步action的分发
export const fetchData = () => async (dispatch) => {dispatch({ type: 'FETCH_DATA_BEGIN' });try {const response = await fetch('/api/data');const data = await response.json();dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });} catch (error) {dispatch({ type: 'FETCH_DATA_FAILURE', payload: error });}
};

在组件中调用接口函数

// 组件中调用接口
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { fetchData } from './actions';const MyComponent = () => {const dispatch = useDispatch();useEffect(() => {dispatch(fetchData());}, [dispatch]);return (<div>{/* 显示组件内容 */}</div>);
};export default MyComponent;

RTK

内置了redux-trunk中间件,调用createAsyncThunk函数来实现,只返回一个promise,RTK会自动处理promise的三种状态。他会为你生成三个特殊的action类型:[type]/pending、[type]/fulfilled 和 [type]/rejected。这些特殊的action类型对应于异步操作的三个阶段。当然在组件中,可以使用useSelector钩子来访问这些状态。

// 引入createAsyncThunk函数
import { createAsyncThunk } from '@reduxjs/toolkit';export const fetchData = createAsyncThunk('fetchData', async () => {const response = await fetch('/api/data');const data = await response.json();return data;
});

在组件中调用接口函数,同时在组件中用useSelector钩子访问这些状态

// 组件中调用接口,基本相同
import ......
import { useSelector } from 'react-redux';
// ...useEffect(() => {dispatch(fetchData());}, [dispatch, count]); // 这里会有不同// ...// 在组件中用useSelector钩子访问这些状态
const userFetchStatus = useSelector((state) => state.user.fetch.status);
const user = useSelector((state) => state.user.fetch.fulfilled);switch (userFetchStatus) {case 'pending':return <p>Loading...</p>;case 'fulfilled':return <p>User fetched successfully: {JSON.stringify(user)}</p>;case 'rejected':return <p>Failed to fetch user: {userFetchStatus.error}</p>;default:return null;
}export default MyComponent;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/852662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用甲骨文云arm服务器安装宝塔时nginx无法卸载

使用甲骨文云arm服务器安装宝塔 其他环境都能安装上 唯独nginx安装完不运行 卸载了几次以后还无法卸载了. 修复 重启都不行. 差点就重建主机了. 最后靠下面的命令 就卸载掉了 然后重装就把nginx安装好了 mv /www/server/nginx/sbin/nginx /tmp/nginx_back mv /etc/in…

React Redux

React Redux是Redux的官方React UI绑定层。它允许您的React组件从Redux存储读取数据&#xff0c;并将操作分派到存储以更新状态。redux是一个管理状态数据state的容器。提供了可预测的状态管理。 React Redux 8.x需要React 16.8.3或更高版本/Rect Native 0.59或更高&#xff0c…

在AMD GPU上加速大型语言模型的Flash Attention

Accelerating Large Language Models with Flash Attention on AMD GPUs — ROCm Blogs 引言 在这篇博客文章中&#xff0c;我们将指导您如何在AMD GPU上安装Flash Attention&#xff0c;并提供与在PyTorch中标准SDPA比较其性能的基准测试。我们还将测量Hugging Face中多个大型…

软件开发工程师的工作内容

软件开发&#xff0c;通俗说就是写程序&#xff0c;就是把一串一串的命令组合起来&#xff0c;让它来替我们完成某种特定任务。软件开发工程师就是从事软件开发相关工作的人员的统称。 在软件开发的整个流程中&#xff0c;软件开发工程师最主要负责的阶段是软件的编码阶段&…

【Java】解决Java报错:FileNotFoundException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 文件路径错误2.2 文件名拼写错误2.3 文件权限问题2.4 文件路径未正确拼接 3. 解决方案3.1 检查文件路径3.2 使用相对路径和类路径3.3 检查文件权限3.4 使用文件选择器 4. 预防措施4.1 使用配置文件4.2 使用日志记录4.3 使用单元测…

几分钟带你初步了解人工智能

目录 1. 什么是人工智能&#xff1f; 2. 人工智能的发展 2.1 人工智能的发展可以追溯到20世纪50年代。以下是人工智能发展的主要阶段&#xff1a; 3.人工智能发展的利与弊 4.人工智能算法有哪些&#xff1f; 4.1 人工智能算法包括线性回归、逻辑回归、决策树、朴素贝叶斯、…

上网行为管理的作用是什么?有哪些上网行为管理软件?

上网行为管理在现代企业及家庭环境中扮演着至关重要的角色&#xff0c;其作用不仅限于提升网络安全性&#xff0c;还涉及保护企业信息安全、提高员工工作效率等多个方面。以下将详细阐述上网行为管理的作用&#xff0c;并介绍几款主流的上网行为管理软件。 一、上网行为管理的作…

Neo4j 桌面版打不开踩坑贴

真的踩坑。。。没有人告诉我为啥桌面版和社区版不能一起下啊&#xff01;&#xff01; 我是先下载了社区版之后再下载的桌面版&#xff0c;结果桌面版界面一直打不开。 尝试了网上多种办法都没效果&#xff0c;好多都是说jdk不兼容导致无法打开&#xff0c;让我从JDK 17 ->…

m2_python字符串-索引与切片

# 索引&#xff1a;查找存取字符串中某一个位置元素[]s "sensizlik"for i in s:print(i)print(s[0]) # 第一个元素 print(s[-1]) # -1倒数第一个元素 print(s[-2]) # -2倒数第二个元素 print("len", len(s)) i 0 while i < len(s):print(s[i…

AUTOSAR平台中的信息安全标准模块

面向MCU端的AUTOSAR CP平台加密组件——Crypto ECU中所有的软件单元都遭受到信息安全攻击的可能。AUTOSAR为保障ECU信息和数据安全&#xff0c;定义了CRYPTO 组件,包含 SecOC、KeyM、IdsM、Csm、CryIf 和Crypto Driver 等标准模块。CRYPTO组件提供各种加解密算法以及密钥管理功…

物联网对智慧驾考应用的价值

随着物联网技术的快速发展&#xff0c;传统行业正经历着前所未有的变革。在智慧驾考领域&#xff0c;4G DTU&#xff08;数据传输单元&#xff09;和工业路由器的应用&#xff0c;不仅提升了考试的规范性和效率&#xff0c;更为驾考行业带来了深远影响。作为工业物联网的资深工…

JVM 类加载器的工作原理

JVM 类加载器的工作原理 类加载器&#xff08;ClassLoader&#xff09;是一个用于加载类文件的子系统&#xff0c;负责将字节码文件&#xff08;.class 文件&#xff09;加载到 JVM 中。Java 类加载器允许 Java 应用程序在运行时动态地加载、链接和初始化类。 2. 类加载器的工…

metersphere提取的字典需要修改其中某个key的值后作为下一接口入参

在测试过程中遇到这样的一种场景&#xff0c;下一个接口的某个字段入参为一个json对象&#xff0c;该对象的值是上一个接口返回的内容&#xff0c;但是其中的某个值不是&#xff0c;需要修改后才能作为下个接口的入参整体传入 上一个接口返回的内容如下&#xff1a; {"s…

今年的就业环境不容乐观,你想好怎么应对了吗

今年的就业环境不容乐观&#xff0c;你想好怎么应对了吗 毕业生进入职场的历程往往充满挑战和未知&#xff0c;尤其是在当前经济环境下&#xff0c;失业问题愈发凸显。本文通过分享几位年轻人的真实经历&#xff0c;剖析大学生及职场人士面临的困境&#xff0c;并提供应对策略…

手把手带你搭建一个语音对话机器人,5分钟定制个人AI小助手(新手入门篇)

写在前面 如果你的身边有一个随时待命、聪明绝顶的AI小助手&#xff0c;能够听懂你的话&#xff0c;理解你的需求&#xff0c;用温暖的声音回应你&#xff0c;会是一种什么体验&#xff1f; 今天&#xff0c;带大家一起搭建一个语音对话机器人&#xff0c;拥有一个专属的个人…

Python中的“*”和“**”

1.接受任意长度形参&#xff0c;组成turple def function(*args):# type(args)turple# args(1, 2, 3, 4)print(args)ant0for i in range(len(args)):antargs[i]return antprint(function(1,2,3,4)) # 102.接受任意长度形参&#xff0c;组成dict def function(**args):# type…

games101作业7光线追踪 含多线程和微表面提高

对于光线追踪进行综合运用。 光线与三角形求交 其它的emit那些&#xff0c;现在先不用管&#xff0c;后面看看作用是什么。 inline Intersection Triangle::getIntersection(Ray ray) {Intersection inter;if (dotProduct(ray.direction, normal) > 0)//光线从里面打&…

[Shell编程学习路线]——深入理解Shell编程中的变量(理论与实例)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f6e0;️Shell编程专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月12日11点40分 &#x1f004;️文章质量&#xff1a;95分 文章目录 ————前言———— 1 自定义变量 &#x1fae0;…

Zynq学习笔记--AXI4-Stream到视频输出IP是如何工作的?

目录 1. 简介 2. 原理详解 2.1 示例工程 2.2 AXI4-Stream to Video Out 3. Master/Slave Timing Mode 3.1 Slave Timing Mode 3.2 Master Timing Mode 4. 总结 1. 简介 本文主要介绍了 AXI4-Stream 到视频输出 的内容。其中&#xff0c;示例工程展示了一个具体的设计&…

GitLab教程(五):高效的工作模式——Feature Branching

文章目录 1.什么是Feature Branching2.Feature Branching的Git实践 1.什么是Feature Branching 特性分支&#xff08;Feature Branching&#xff09;是一种软件开发工作流&#xff0c;尤其在使用Git或其他版本控制系统时被广泛采用。这种策略鼓励开发者为每一个新功能、改进或…