react-redux useSelector钩子 学习样例 + 详细解析

(一)react-redux useSelector 学习样例 + 详细解析 

创建一个新项目,将依赖正确安装:

npx create-react-app my-redux-app
cd my-redux-app# 安装 Redux 和 React-Redux
npm install redux react-redux# 安装 ajv
npm install ajv# 安装最新的 react-scripts
npm install react-scripts@latestnpm install antd
my-redux-app/
├── public/
│   └── index.html
├── src/
│   ├── actions/
│   │   └── index.js
│   ├── components/
│   │   └── GiftSelector.js
│   ├── reducers/
│   │   └── index.js
│   ├── store/
│   │   └── index.js
│   ├── App.js
│   └── index.js
└── package.json

 1.src/actions/index.js

export const SET_GIFT_ITEMS = 'SET_GIFT_ITEMS';export const setGiftItems = (giftItems) => ({type: SET_GIFT_ITEMS,payload: giftItems,
});

2.src/reducers/index.js

import { combineReducers } from 'redux';
import { SET_GIFT_ITEMS } from '../actions';const initialSettingInfo = {giftOptionIndex: 0,giftItems: [],
};const settingInfo = (state = initialSettingInfo, action) => {switch (action.type) {case SET_GIFT_ITEMS:return {...state,giftItems: action.payload,};default:return state;}
};const rootReducer = combineReducers({settingInfo,
});export default rootReducer;

3.src/store/index.js

import { createStore } from 'redux';
import rootReducer from '../reducers';const store = createStore(rootReducer);export default store;

4.src/components/GiftSelector.js

import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Select, Button } from 'antd';
import { setGiftItems } from '../actions';const { Option } = Select;const giftList = [{ giftId: 1, giftName: '礼物1' },{ giftId: 2, giftName: '礼物2' },{ giftId: 3, giftName: '礼物3' },
];const GiftSelector = () => {const [selectedGiftId, setSelectedGiftId] = useState(null);const dispatch = useDispatch();const giftItems = useSelector((state) => state.settingInfo.giftItems);const handleChange = (value) => {setSelectedGiftId(value);};const handleAddGift = () => {if (selectedGiftId) {const selectedGift = giftList.find((gift) => gift.giftId === selectedGiftId);const newGiftItems = [...giftItems, selectedGift];dispatch(setGiftItems(newGiftItems));}};return (<div><Select style={{ width: 200 }} onChange={handleChange} placeholder="选择一个礼物">{giftList.map((gift) => (<Option key={gift.giftId} value={gift.giftId}>{gift.giftName}</Option>))}</Select><Button type="primary" onClick={handleAddGift} style={{ marginLeft: 10 }}>添加</Button><div><h3>已添加的礼物:</h3>{giftItems.map((gift) => (<div key={gift.giftId}>{gift.giftName}</div>))}</div></div>);
};export default GiftSelector;

5.src/App.js

import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import GiftSelector from './components/GiftSelector';
import 'antd/dist/antd.css';const App = () => {return (<Provider store={store}><GiftSelector /></Provider>);
};export default App;

6.src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);

运行项目

npm start

功能描述

  1. GiftSelector 组件

    • 使用 Select 组件展示礼物列表。
    • 使用 Button 组件添加选中的礼物。
    • 添加的礼物展示在下方。
  2. 状态管理

    • 使用 Redux 管理 giftItems 状态。
    • 动作 setGiftItems 用于更新 giftItems

这个项目展示了如何使用 antd 组件结合 Redux 来实现礼物选择和添加功能。

 

>>>>作用

(1)获取 Redux 状态

  • useSelector 是 React-Redux 库中的一个钩子函数,用于从 Redux 状态树中提取数据。

(2)通过 Selector 提取特定状态

  • useSelector 接受一个回调函数,该回调函数会被调用并传递 Redux 状态树作为参数。
  • 在这个回调函数中,你可以从状态树中选择你需要的部分状态。

(3)具体实现

  • (state) => state.settingInfo.giftItems 是传递给 useSelector 的回调函数。
  • state 参数代表整个 Redux 状态树。
  • state.settingInfo 获取 settingInfo 这个 reducer 管理的状态部分。
  • state.settingInfo.giftItems 获取 settingInfo 中的 giftItems 数组。

(4)结果

  • 返回的 giftItems 就是 settingInfo 中的 giftItems 数组,即当前已经添加的礼物列表。
  • 当 settingInfo.giftItems 发生变化时,React 组件会重新渲染以反映最新状态。

让我们详细说明一下数据更新的流程。以我们的 GiftSelector 示例为例,具体流程包括以下步骤:

1. 初始状态

在 Redux 中,giftItems 的初始状态为空数组。

const initialState = {giftOptionIndex: 0,giftItems: [],
};

2. 用户选择礼物并点击添加按钮

用户通过 Ant Design Select 组件选择一个礼物,并点击 "添加" 按钮触发操作。

3. 触发 Redux Action

点击 "添加" 按钮时,触发 handleAddGift 函数,这会分发一个 setGiftItems action 来更新状态。

const handleAddGift = () => {if (selectedGiftId) {const selectedGift = giftList.find((gift) => gift.giftId === selectedGiftId);const newGiftItems = [...giftItems, selectedGift];dispatch(setGiftItems(newGiftItems));}
};

4. Action 创建器

setGiftItems action 创建器返回一个 action 对象。

// src/actions/index.js
export const SET_GIFT_ITEMS = 'SET_GIFT_ITEMS';export const setGiftItems = (giftItems) => ({type: SET_GIFT_ITEMS,payload: giftItems,
});

5. Redux Reducer 处理 Action

Redux store 接收到 SET_GIFT_ITEMS action 后,reducer 处理这个 action 并返回更新的状态。

// src/reducers/index.js
const initialSettingInfo = {giftOptionIndex: 0,giftItems: [],
};const settingInfo = (state = initialSettingInfo, action) => {switch (action.type) {case SET_GIFT_ITEMS:return {...state,giftItems: action.payload,};default:return state;}
};

6. Store 更新状态

Redux store 根据 reducer 的返回值更新 settingInfo.giftItems 状态。

7. React 组件重新渲染

由于 useSelector 钩子将 giftItems 状态映射到组件中,当 Redux 状态更新时,组件会自动重新渲染以反映最新的状态。

const giftItems = useSelector((state) => state.settingInfo.giftItems);

示例流程

让我们具体展示一次用户操作和状态更新的流程:

(1)初始状态

{giftOptionIndex: 0,giftItems: [],
}

(2)用户选择礼物

  • 用户选择 giftId: 1 的礼物(礼物1)。
  • selectedGiftId 更新为 1。

(3)点击 "添加" 按钮

  • 调用 handleAddGift 函数。

  • newGiftItems 计算为 [{ giftId: 1, giftName: '礼物1' }]

  • 分发 setGiftItems(newGiftItems)

(4)Reducer 处理 Action

  • 接收到 SET_GIFT_ITEMS action

  • 返回更新后的状态:

{giftOptionIndex: 0,giftItems: [{ giftId: 1, giftName: '礼物1' }],
}

(5)组件重新渲染

  • GiftSelector 组件由于 giftItems 状态更新而重新渲染。

  • 新状态 giftItems 映射到组件,UI 显示已添加的礼物:

<div key={gift.giftId}>{gift.giftName}</div>

这就是完整的数据更新流程:

  • 用户操作触发事件,事件分发 action,reducer 处理 action 并返回新状态,store 更新状态,React 组件重新渲染以反映新状态。

总结

  1. 用户选择礼物。
  2. 点击按钮分发 action。
  3. Reducer 接收 action 并更新状态。
  4. Redux store 更新状态。
  5. useSelector 获取最新状态,组件重新渲染 UI。

(二)useSelector

useSelector 是 React-Redux 提供的一个钩子,用于从 Redux 的状态树中提取部分数据。

基本概念

useSelector 的主要作用是:

  1. 从 Redux 状态树中选择(或提取)数据。
  2. 在选中的数据发生变化时自动重新渲染组件。

例子和解释

假设我们在 Redux 状态中存储了一些礼物信息,并且希望在组件中获取和显示这些礼物信息。

Redux 状态结构

首先,假设我们的 Redux 状态结构如下:

const initialState = {settingInfo: {giftOptionIndex: 0,giftItems: [], // 这里存放礼物数组},
};

 使用 useSelector 钩子从 Redux 状态中获取数据

在组件中,我们使用 useSelector 钩子从 Redux 状态中提取 giftItems 数据:

import React from 'react';
import { useSelector } from 'react-redux';const GiftList = () => {// 使用 useSelector 提取 giftItemsconst giftItems = useSelector((state) => state.settingInfo.giftItems);return (<div><h3>已添加的礼物:</h3>{giftItems.map((gift) => (<div key={gift.giftId}>{gift.giftName}</div>))}</div>);
};export default GiftList;

详细步骤

  • 引入 useSelector: 首先确保从 react-redux 引入了 useSelector
import { useSelector } from 'react-redux';
  • 定义 Selector 回调函数

useSelector 接受一个回调函数,这个回调函数有一个参数 state,代表整个 Redux 状态树。

const giftItems = useSelector((state) => state.settingInfo.giftItems);

上面的代码意思是:

  • 从 Redux 状态树中选择 state.settingInfo.giftItems 这个部分。
  • giftItems 会得到 state.settingInfo.giftItems 的值。

输出提取的数据: 在 JSX 中,可以使用 giftItems 来输出数据,例如:

{giftItems.map((gift) => (<div key={gift.giftId}>{gift.giftName}</div>
))}

工作原理

  1. 获取当前状态useSelector 从 Redux store 中获取当前状态(或数据)。

  2. 订阅状态变化: 当所选择的状态部分发生变化时,useSelector 会让组件重新渲染,以反映最新状态。

  3. 返回选中的状态giftItems 存储了最新的被选中的状态部分的数据。

在这个完整的例子中,useSelector 钩子用于从 Redux 状态树中提取 settingInfo.giftItems。当 giftItems 发生变化时,组件会自动重新渲染并显示最新的礼物列表。

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

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

相关文章

IP数据云 识别和分析tor、proxy等各类型代理

在网络上使用代理&#xff08;tor、proxy、relay等&#xff09;进行访问的目的是为了规避网络的限制、隐藏真实身份或进行其他的不正当行为。 对代理进行识别和分析可以防止恶意攻击、监控和防御僵尸网络和提高防火墙效率等&#xff0c;同时也可以对用户行为进行分析&#xff…

《Django 5 By Example》阅读笔记:p76-p104

《Django 5 By Example》学习第4天&#xff0c;p76-p104总结&#xff0c;总计29页。 一、技术总结 1.环境变量管理 这里作者使用的是&#xff1a;python-decouple&#xff0c;本人在实际项目中使用的是python-dotenv&#xff0c;这里只是简单的使用&#xff0c;感觉两者差不…

【IC每日一题:IC常用模块--RR/handshake/gray2bin】

IC每日一题&#xff1a;IC常用模块--RR/handshake/gray2bin 1 RR仲裁器2 异步握手信号处理3 格雷码和二进制相互转换 1 RR仲裁器 应用&#xff1a;在多个FIFO请求pop时存在仲裁策略&#xff0c;还有比如多master申请总线控制权的仲裁等这些应用场合&#xff1b;假如当前是最高…

【Visual Studio】使用VS调试(Debug)

确保在Debug模式下而不是Release 打断点(break point) 直接在有代码的行前单击&#xff0c;会出现红色的点(再次单击会取消)&#xff1b;或者光标停留在某行&#xff0c;按F9 这意味着程序当执行到这一行时会终止 在打完断点后点击”本地Windows调试器“或者按F5 往下翻会…

基于RK3568J多网口电力可信物联网关解决方案

前言 随着工业物联网的普及和功能越来越强大&#xff0c;边缘计算网关应运而生。 边缘计算有效降低了云端服务器的负载、大大降低了带宽的占用&#xff0c;同时也为本地化的区域自治提供了便利条件。 边缘计算网关&#xff0c;完美地发挥了“边”与“端” 结合优势&#xff0c…

⾃动化运维利器Ansible-基础

Ansible基础 一、工作原理二、快速入门2.1 测试所有资产的网络连通性2.2 发布文件到被管理节点(资产) 三、资产(被管理节点)3.1 静态资产3.1.1 自定义资产3.1.2 自定义资产的使用3.1.3 资产选择器 四、Ansible Ad-Hoc 命令4.1 模块类型4.1.1 command & shell 模块4.1.2 cop…

SpringBoot实战(三十一)集成iText5,实现RSA签署PDF

目录 一、什么是电子签章?1.1 定义1.2 电子签章的工作原理1.3 电子签章的优势二、准备工作:证书生成、印章生成2.1 证书生成2.2 印章生成三、Java代码实现 RSA 签署 PDF3.1 坐标签署3.2 关键字签署3.3 日期签署3.4 骑缝章签署3.5 文本域签署一、什么是电子签章? 1.1 定义 电…

vue面试题7|[2024-11-14]

问题1&#xff1a;什么是渐进式框架? vue.js router vuex element ...插件 vue.js 渐0 router 渐1 vuex 渐2 vue.js只是一个核心库&#xff0c;比如我再添加一个router或者vuex&#xff0c;不断让项目壮大&#xff0c;就是渐进式框…

【力扣热题100】[Java版] 刷题笔记-169. 多数元素

题目&#xff1a;169. 多数元素 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 解题思路 该题目的核心点是&#xff1a;元素出现…

Dolby TrueHD和Dolby Digital Plus (E-AC-3)编码介绍

文章目录 1. Dolby TrueHD特点总结 2. Dolby Digital Plus (E-AC-3)特点总结 Dolby TrueHD 与 Dolby Digital Plus (E-AC-3) 的对比 Dolby TrueHD和Dolby Digital Plus (E-AC-3) 是两种高级的杜比音频编码格式&#xff0c;常用于蓝光影碟、流媒体、影院等高品质音频传输场景。它…

第三十一天|贪心算法| 56. 合并区间,738.单调递增的数字 , 968.监控二叉树

目录 56. 合并区间 方法1&#xff1a;fff 看方法2&#xff1a;fff优化版 方法3&#xff1a; 738.单调递增的数字 968.监控二叉树&#xff08;贪心二叉树&#xff09; 56. 合并区间 判断重叠区间问题&#xff0c;与452和435是一个套路 方法1&#xff1a;fff 看方法2&am…

火车车厢重排问题,C++详解

目录 实验题目 解题思路 1先看缓冲队列队头是否符合要求 2看队头元素是否符合要求 完整代码 运行结果 实验题目 火车车厢重排问题 实验说明&#xff1a;转轨站示意图如下&#xff1a; 火车车厢重排过程如下&#xff1a; 火车车厢重排算法伪代码如下&#xff1a; 解题思路…

算法学习第一弹——C++基础

早上好啊&#xff0c;大佬们。来看看咱们这回学点啥&#xff0c;在前不久刚出完C语言写的PTA中L1的题目&#xff0c;想必大家都不过瘾&#xff0c;感觉那些题都不过如此&#xff0c;所以&#xff0c;为了我们能更好的去处理更难的题目&#xff0c;小白兔决定奋发图强&#xff0…

LabVIEW大数据处理

在物联网、工业4.0和科学实验中&#xff0c;大数据处理需求逐年上升。LabVIEW作为一款图形化编程语言&#xff0c;凭借其强大的数据采集和分析能力&#xff0c;广泛应用于实时数据处理和控制系统中。然而&#xff0c;在面对大数据处理时&#xff0c;LabVIEW也存在一些注意事项。…

AUTOSAR_EXP_ARAComAPI的7章笔记(3)

☞返回总目录 相关总结&#xff1a;AutoSar AP简单多绑定总结 7.3 多绑定 如在 5.4.3 小节中简要讨论的&#xff0c;某个代理类 / 骨架类的不同实例之间的技术传输是不同的&#xff0c;多绑定描述了这种情况的解决方案。多种技术原因都可能导致这种情况出现&#xff1a; 代…

一键生成本地SSL证书:打造HTTPS安全环境

一键生成本地SSL证书&#xff1a;打造HTTPS安全环境 日光下的寒林没有一丝杂质&#xff0c;空气里的冰冷仿佛来自故乡遥远的北国&#xff0c;带着一些相思&#xff0c;还有细微几至不可辨认的骆驼的铃声。–《心美&#xff0c;一切皆美》 在本地开发环境中启用 HTTPS 一直是许多…

mysql 配置文件 my.cnf 增加 lower_case_table_names = 1 服务启动不了的原因

原因&#xff1a;在MySQL8.0之后的版本&#xff0c;只允许在数据库初始化时指定&#xff0c;之后不允许修改了 mysql 配置文件 my.cnf 增加 lower_case_table_names 1 服务启动不了 报错信息&#xff1a;Job for mysqld.service failed because the control process exited …

Zookeeper的安装与使用

一、简介 1.1、概念 ZooKeeper 是一个开源的分布式协调服务&#xff0c;主要用于解决分布式系统中的数据一致性问题。它提供了一种可靠的机制来管理和协调分布式系统的各个节点。ZooKeeper 的设计目标是简化分布式应用的开发&#xff0c;提供简单易用的接口和高性能、高稳定性…

Vue3.js - 一文看懂Vuex

1. 前言 Vuex 是 Vue.js 的官方状态管理库&#xff0c;用于在 Vue 应用中管理组件之间共享的状态。Vuex 适用于中大型应用&#xff0c;它将组件的共享状态集中管理&#xff0c;可以避免组件间传递 props 或事件的复杂性。 2. 核心概念 我们可以将Vuex想象为一个大型的Vue&…

图论-代码随想录刷题记录[JAVA]

文章目录 前言Floyd 算法dijkstra&#xff08;朴素版&#xff09;最小生成树之primkruskal算法 前言 新手小白记录第一次刷代码随想录 1.自用 抽取精简的解题思路 方便复盘 2.代码尽量多加注释 3.记录踩坑 4.边刷边记录&#xff0c;更有成就感&#xff01; 5.解题思路绝大部分来…