位置: IT常识 - 正文

React - Redux Hooks的使用细节详解

编辑:rootadmin
React - Redux Hooks的使用细节详解 文章目录Redux HooksRedux中Hooks介绍Redux中Hooks使用Redux HooksRedux中Hooks介绍

推荐整理分享React - Redux Hooks的使用细节详解,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

在之前的redux开发中,为了让组件和redux结合起来,我们使用了react-redux库中的connect:

但是这种方式必须使用高阶函数结合返回的高阶组件;

并且必须编写:mapStateToProps和 mapDispatchToProps映射的函数, 具体使用方式在前面文章有讲解;

在Redux7.1开始,提供了Hook的方式,在函数组件中再也不需要编写connect以及对应的映射函数了

useSelector的作用是将state映射到组件中:

参数一: 要求传入一个回调函数, 会将state传递到该回调函数中; 回调函数的返回值要求是一个对象, 在对象编写要使用的数据, 我们可以直接对这个返回的对象进行解构, 拿到我们要使用state中的数据

const { counter } = useSelector((state) => { return { counter: state.counter.counter }})

参数二: 可以进行比较来决定是否组件重新渲染;

React - Redux Hooks的使用细节详解

useSelector默认会比较我们返回的两个对象是否相等;

如何可以比较呢?

在useSelector的第二个参数中, 传入react-redux库中的shallowEqual函数就可以进行比较import { shallowEqual } from 'react-redux'const { counter } = useSelector((state) => ({ counter: state.counter.counter}), shallowEqual)

也就是我们必须返回两个完全相等的对象才可以不引起重新渲染;

useDispatch非常简单,就是调用useDispatch这个Hook, 就可以直接获取到dispatch函数,之后在组件中直接使用即可;

const dispatch = useDispatch()

我们还可以通过useStore来获取当前的store对象(了解即可, 不建议直接操作store对象);

Redux中Hooks使用

我们来使用Redux的Hooks在App组件实现一个计数器, 在App的子组件中实现一个修改message的案例:

首先我们先创建一个简单的store

// store/modules/counter.jsimport { createSlice } from "@reduxjs/toolkit";const counterSlice = createSlice({ name: "counter", initialState: { counter: 10, message: "Hello World" }, reducers: { changeNumberAction(state, { payload }) { state.counter = state.counter + payload }, changeMessageAction(state, {payload }) { state.message = payload } }})export const { changeNumberAction, changeMessageAction } = counterSlice.actionsexport default counterSlice.reducer// store/index.jsimport { configureStore } from "@reduxjs/toolkit";import counterSlice from "./modules/counter"const store = configureStore({ reducer: { counter: counterSlice }})export default store

要使用react-redux库需要导入Provider对App组件进行包裹

import React from "react"import ReactDOM from "react-dom/client"import { Provider } from "react-redux"import App from "./12_Redux中的Hooks/App"import store from "./12_Redux中的Hooks/store"const root = ReactDOM.createRoot(document.querySelector("#root"))root.render( <Provider store={store}> <App/> </Provider>)

在组件时使用useSelector和useDispatch实现获取store中的数据和修改store中数据的操作

import React, { memo } from 'react'import { useDispatch, useSelector } from 'react-redux'import { changeMessageAction, changeNumberAction } from './store/modules/counter'// 子组件Homeconst Home = memo(() => { console.log("Home组件重新渲染") // 通过useSelector获取到store中的数据 const { message } = useSelector((state) => ({ message: state.counter.message })) // useDispatch获取到dispatch函数 const dispatch = useDispatch() function changeMessage() { dispatch(changeMessageAction("Hello ChenYq")) } return ( <div> <h2>{message}</h2> <button onClick={changeMessage}>修改message</button> </div> )})// 根组件Appconst App = memo(() => { console.log("App组件重新渲染") // 通过useSelector获取到store中的数据 const { counter } = useSelector((state) => ({ counter: state.counter.counter })) // useDispatch获取到dispatch函数 const dispatch = useDispatch() function changeNumber(num) { dispatch(changeNumberAction(num)) } return ( <div> <h2>当前计数: {counter}</h2> <button onClick={() => changeNumber(1)}>+1</button> <button onClick={() => changeNumber(-1)}>-1</button> <Home/> </div> )})export default App

现在我们已经在组件中使用并且修改了了store中的数据, 但是现在还有一个小问题(性能优化)

当App组件中修改了counter时, App组件会重新渲染这个是没问题的; 但是Home组件中使用的是message, 并没有使用counter, 却也会重新渲染; 同样的在Home子组件中修改了message, 根组件App也会重新渲染; 这是因为在默认情况下useSelector是监听的整个state, 当state发生改变就会导致组件重新渲染

要解决这个问题就需要使用useSelector的第二个参数来控制是否需要重新渲染, 我们只需要在useSelector函数中传入react-redux库中的shallowEqual函数即可, 它内部会自动进行一个浅层比较, 当使用的state中的数据确实发生变化的时候才会重新渲染

import React, { memo } from 'react'import { useDispatch, useSelector, shallowEqual } from 'react-redux'import { changeMessageAction, changeNumberAction } from './store/modules/counter'// 子组件Homeconst Home = memo(() => { console.log("Home组件重新渲染") const { message } = useSelector((state) => ({ message: state.counter.message }), shallowEqual) const dispatch = useDispatch() function changeMessage() { dispatch(changeMessageAction("Hello ChenYq")) } return ( <div> <h2>{message}</h2> <button onClick={changeMessage}>修改message</button> </div> )})// 根组件Appconst App = memo(() => { console.log("App组件重新渲染") // 通过useSelector获取到store中的数据 const { counter } = useSelector((state) => ({ counter: state.counter.counter }), shallowEqual) // useDispatch获取到dispatch函数 const dispatch = useDispatch() function changeNumber(num) { dispatch(changeNumberAction(num)) } return ( <div> <h2>当前计数: {counter}</h2> <button onClick={() => changeNumber(1)}>+1</button> <button onClick={() => changeNumber(-1)}>-1</button> <Home/> </div> )})export default App
本文链接地址:https://www.jiuchutong.com/zhishi/300197.html 转载请保留说明!

上一篇:Tomcat服务器部署+Web项目搭建(tomcat服务器在哪个位置)

下一篇:翻译: 详细图解Transformer多头自注意力机制 Attention Is All You Need(图幅翻译)

  • 小米11定位设置在哪里设置(小米11定位设置在哪里找)

    小米11定位设置在哪里设置(小米11定位设置在哪里找)

  • 抖音小店要扣多少佣金(抖音小店扣多少分会封店)

    抖音小店要扣多少佣金(抖音小店扣多少分会封店)

  • 文档已被其他应用程序锁定(文档已被其他应用锁定)

    文档已被其他应用程序锁定(文档已被其他应用锁定)

  • 抖音可以批量取消关注吗(抖音可以批量取关人吗)

    抖音可以批量取消关注吗(抖音可以批量取关人吗)

  • 无线电报原理(无线电电报原理)

    无线电报原理(无线电电报原理)

  • 微头条展现量什么意思(微头条1000展现量)

    微头条展现量什么意思(微头条1000展现量)

  • 手机系统工具在哪里找(手机怎么设置两个系统)

    手机系统工具在哪里找(手机怎么设置两个系统)

  • 网络lp地址是什么意思(网络地址 ip地址)

    网络lp地址是什么意思(网络地址 ip地址)

  • wps怎么返回上一步(wps怎么返回上一步快捷键)

    wps怎么返回上一步(wps怎么返回上一步快捷键)

  • 微信圈子怎么变现(微信圈子怎么换头像)

    微信圈子怎么变现(微信圈子怎么换头像)

  • 怎么查拼多多一年账单(怎么查拼多多一个月花了多少钱)

    怎么查拼多多一年账单(怎么查拼多多一个月花了多少钱)

  • 没备份恢复出厂后找回联系人(没备份恢复出厂后找回联系人华为)

    没备份恢复出厂后找回联系人(没备份恢复出厂后找回联系人华为)

  • 一加7支持多少快充(一加7支持多少w)

    一加7支持多少快充(一加7支持多少w)

  • 苹果7充电越充越少怎么回事(苹果7充电越充越少)

    苹果7充电越充越少怎么回事(苹果7充电越充越少)

  • 11支持双卡吗(iphone14pro支持双卡吗)

    11支持双卡吗(iphone14pro支持双卡吗)

  • 苹果手机cydia在哪里(苹果cydia怎么用)

    苹果手机cydia在哪里(苹果cydia怎么用)

  • 网易云年轮说怎么单曲购买(网易云年标有什么用)

    网易云年轮说怎么单曲购买(网易云年标有什么用)

  • 水滴筹证明怎么删除(水滴筹钱证明真实怎么写)

    水滴筹证明怎么删除(水滴筹钱证明真实怎么写)

  • 小米手环4有NFC吗(小米8手环功能介绍)

    小米手环4有NFC吗(小米8手环功能介绍)

  • 口袋直播怎么下载(口袋直播下载安卓版)

    口袋直播怎么下载(口袋直播下载安卓版)

  • vivos1处理器是多少(vivos1处理器相当于骁龙多少)

    vivos1处理器是多少(vivos1处理器相当于骁龙多少)

  • 芒果tv如何发弹幕(芒果tvhd版本怎么发弹幕)

    芒果tv如何发弹幕(芒果tvhd版本怎么发弹幕)

  • 桌面图标删不掉怎么解决?(桌面图标删不掉怎么回事)

    桌面图标删不掉怎么解决?(桌面图标删不掉怎么回事)

  • 埃尔姆利国家自然保护区里的一只文须雀,英格兰肯特郡 (© Mark Bridger/Offset by Shutterstock)(埃姆雷莫尔)

    埃尔姆利国家自然保护区里的一只文须雀,英格兰肯特郡 (© Mark Bridger/Offset by Shutterstock)(埃姆雷莫尔)

  • 工资个人所得税标准表
  • 待认证进项税是借方还是贷方
  • 成立日期是注册日期吗
  • 微企怎么申请补贴
  • 民办非盈利企业注册
  • 购入资产的入账价格一般是以该项资产的什么反应
  • 调整凭证分录
  • 公司试驾车购置税怎么交
  • 长期股权投资减值准备借贷方向
  • 代收水电气费加盟
  • 生产成本福利费用汇算清缴嘛
  • 服务行业有哪些工作
  • 企业个人所得税申报系统官网
  • 预收账款开票可以抵扣吗
  • 工程结算收入和应收账款的区别
  • 申报是不是就是报税
  • 外籍人员取得数月奖金怎么交税
  • 公允出资税务处理怎么做?
  • 城镇土地使用税征收标准及计算方法
  • 用人单位逾期未缴纳社会保险费可能会使用的文书
  • 微软系统管理员账号
  • 公司车辆违章怎么办
  • 线上网速测试
  • php调用sql
  • PHP:pcntl_wexitstatus()的用法_PCNTL函数
  • php文件上传用什么请求方法
  • php数字增1
  • opencv训练模型教程
  • vue-introjs
  • dematel模型有什么缺点
  • pytorch的环境配置
  • 新手学web前端开发
  • mksquashfs命令
  • php类的定义
  • 小规模纳税人抵税是普票还是专票
  • 驱动开发做得长久吗
  • 车到4s店后还需办什么手续
  • 汇兑损益一级科目
  • 支付增值税税控系统技术维护费用
  • 缴纳残保金工资是实发工资还是应发工资
  • 建筑企业结转成本附件
  • 不良资产处置公司违法吗
  • 车间报销维修费会计科目
  • 红冲凭证怎么做分录
  • 小规模建筑公司开劳务费发票税率
  • 结转本年利润按什么算
  • 咨询费发票能抵扣吗
  • 关联交易现金流
  • 资金账簿印花税减半政策
  • 以现金形式发工资的公司
  • 企业签发转账支票
  • 营改增之后账务怎么处理
  • 员工出差的费用怎么算
  • 小规模纳税人如何申请专票
  • 企业租入设备的会计分录怎么写
  • 行政事业单位支出范围和标准
  • 房租可以提前开票吗
  • 本年利润每个月有余额吗
  • 班车租赁费计入福利费吗
  • sql server查询
  • mysql索引实战
  • Ubuntu安装ssh
  • 重装windows764 位后后如何将apache mysql加入系统服务
  • linux批量替换文件夹名称
  • linux chakan
  • win8系统截图工具快捷键
  • neoDVD.exe - neoDVD是什么进程 有什么用
  • win命令行杀死一个程序
  • windows8开机启动项在哪里设置
  • Linux系统怎么设置中文输入法
  • jquery动态添加
  • shell备份文件脚本
  • cocos 2d x
  • unity2018地形
  • emulator: ERROR: no search paths found in this AVD's configuration. Weird, the AVD's config.ini file
  • java颜色代码对照表图片
  • shell脚本检测文件是否存在
  • 农业方面有哪些有名杂志
  • 济南市中区税务局办税大厅
  • 四川省地方税务局公告2018年第1号
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设