当前位置: 首页 > article >正文

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@latest

npm 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

package.json 

{
  "name": "my-redux-app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.4",
    "redux": "^4.1.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}

 

 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 提取 giftItems
  const 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.kler.cn/a/395237.html

相关文章:

  • android studio 更改gradle版本方法(备忘)
  • react 受控组件和非受控组件
  • Go八股(Ⅴ)map
  • 基于Python 和 pyecharts 制作招聘数据可视化分析大屏
  • 亲测有效:Maven3.8.1使用Tomcat8插件启动项目
  • Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)
  • AR眼镜方案_AR智能眼镜阵列/衍射光波导显示方案
  • jupyter可视化pandas dataframe
  • Spring Boot 异常处理
  • Jmeter中的监听器(三)
  • chat2db调用ollama实现数据库的操作。
  • Docker部署kafka集群
  • go strings查找手册
  • Brave127编译指南 Windows篇:部署depot_tools(三)
  • 借助Aspose.Email,拆分和合并 Outlook PST 文件
  • 计算机课程管理:Spring Boot实现的工程认证路径
  • 1300. 转变数组后最接近目标值的数组和
  • 调试、发布自己的 npm 包
  • 从H264视频中获取宽、高、帧率、比特率等属性信息
  • VUE3中Element table表头动态展示合计信息(不是表尾合计)
  • 【C#/C++】C++/CL中String^的含义和举例,C++层需要调用C#层对象时...
  • 数据结构--数组
  • 算法|牛客网华为机试41-52C++
  • LeetCode-222.完全二叉树的节点个数
  • DVWA靶场通关——SQL Injection篇
  • c++ shared_ptr 常见构造函数