位置: 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(图幅翻译)

  • 奶牛快传怎么下载文件(奶牛快传怎么下载付费文件)

    奶牛快传怎么下载文件(奶牛快传怎么下载付费文件)

  • snkrs上的订单无法取消(snkrs购买了显示无订单)

    snkrs上的订单无法取消(snkrs购买了显示无订单)

  • supercharge充电器是什么意思(华为supercharge充电器)

    supercharge充电器是什么意思(华为supercharge充电器)

  • 华为怎么设置10分钟锁屏(华为怎么设置10秒后拍照)

    华为怎么设置10分钟锁屏(华为怎么设置10秒后拍照)

  • iphone充满电不拔会损耗电池吗(iphone充满电不拔会怎么样)

    iphone充满电不拔会损耗电池吗(iphone充满电不拔会怎么样)

  • 抖音私信被禁言了怎么解决(抖音私信被禁言怎么解封)

    抖音私信被禁言了怎么解决(抖音私信被禁言怎么解封)

  • 已禁用ime是什么意思(已禁用icm是什么意思)

    已禁用ime是什么意思(已禁用icm是什么意思)

  • qqvip到期了个性装扮还有吗(qq超级会员过期了个性装扮还在吗)

    qqvip到期了个性装扮还有吗(qq超级会员过期了个性装扮还在吗)

  • 爱奇艺不能自动播放下一集怎么回事(爱奇艺不能自动播放下一集)

    爱奇艺不能自动播放下一集怎么回事(爱奇艺不能自动播放下一集)

  • 大数据能查到个人什么信息(大数据能查到个人行踪吗)

    大数据能查到个人什么信息(大数据能查到个人行踪吗)

  • word文档开发工具在哪(Word文档开发工具控件灰色)

    word文档开发工具在哪(Word文档开发工具控件灰色)

  • 哪款ipad能插电话卡(ipad支持充电)

    哪款ipad能插电话卡(ipad支持充电)

  • 个人计算机属于什么类型(个人计算机属于小型计算机)

    个人计算机属于什么类型(个人计算机属于小型计算机)

  • 微信视频反的怎么设置(微信视频 反的)

    微信视频反的怎么设置(微信视频 反的)

  • 华为mate30有来电闪光灯吗(华为mate30有来电闪光功能吗怎么设置)

    华为mate30有来电闪光灯吗(华为mate30有来电闪光功能吗怎么设置)

  • 解读华为p30的拍照技巧(华为p30拍摄效果怎么样)

    解读华为p30的拍照技巧(华为p30拍摄效果怎么样)

  •  正在拼单怎么取消订单(正在拼单怎么取消订单)

    正在拼单怎么取消订单(正在拼单怎么取消订单)

  • 无屏助手怎么投屏(无屏助手怎么投屏到电视)

    无屏助手怎么投屏(无屏助手怎么投屏到电视)

  • oppo 新机reno z是什么处理器(oppo reno z刚出来多少钱)

    oppo 新机reno z是什么处理器(oppo reno z刚出来多少钱)

  • 苹果账户设置页(苹果账户设置页取消订阅服务)

    苹果账户设置页(苹果账户设置页取消订阅服务)

  • 手机刷机了能恢复照片(手机刷机了能恢复出厂设置吗)

    手机刷机了能恢复照片(手机刷机了能恢复出厂设置吗)

  • 魅族16如何root(魅族16如何截长图整屏)

    魅族16如何root(魅族16如何截长图整屏)

  • 默认网关不可用什么原因详情(默认网关不可用修复后过一会又不好使了)

    默认网关不可用什么原因详情(默认网关不可用修复后过一会又不好使了)

  • 小规模纳税人增值税可以抵扣吗
  • 小规模减免增值税
  • 金税盘入账的会计分录
  • 融资租赁税率是什么意思
  • 小规模纳税人所得税怎么征收
  • 劳务发票可以抵扣多少
  • 股东归还公司借款,应该记什么科目
  • 收入 合同
  • 资金结存科目余额对应
  • 增值税专票发票代码在哪里看
  • 收到发票付款是抹了零头怎么做账
  • 资产减值损失结转
  • 固定资产融资租赁账务处理
  • 房屋租赁合同样本书
  • 企业办税人员收入怎么算
  • 审核发票的要素
  • 食用盐适用的增值税税率
  • 电子发票收款人和复核人可以是一个人吗
  • 防暑降温列支什么费用
  • 待报解地方预算收入怎么做账
  • 营改增建筑业
  • 工会残保金必须缴纳吗
  • windows10命令提示符怎么用
  • 批量获取文件信息
  • 长期闲置的机器叫什么
  • mac怎么转到苹果系统
  • lsass.exe是什么进程
  • win7为什么显示多重网络
  • win10的病毒隔离有用吗
  • 500万元固定资产管理办法
  • yii框架运行原理
  • ci框架中新建的控制器取不到session
  • php url函数
  • php array search
  • 如何更改telnet端口
  • 增值税普通发票怎么开
  • dict.setdefault()在python中设置默认值
  • python继承例子
  • python for循环遍历
  • 阴影等级是什么
  • 小规模劳务派遣公司税率
  • 库存商品和固定成本区别
  • 无形资产有在建工程吗
  • sqlserver、mysql获取连接字符串步骤
  • 企业所得税的税收筹划
  • 公司法人必须在公司名下缴纳社保吗
  • 厂家给经销商的活动方案怎么写
  • 收到服务费发票可以计入什么科目
  • 其他非流动资产减少的原因
  • 购进商品的运费计入什么科目
  • 个人银行存款要手续费吗
  • 待处理财产损溢借贷增减方向
  • 电商行业的采购
  • 对于审核后的凭证可直接修改对吗
  • 误餐补助标准国家规定
  • 发票盖章需要知道的10个问题
  • sqlserver向表中添加数据用什么命令
  • mysql自动清理数据
  • w10语言栏
  • windows server vista
  • mac adobe flash player一直提示更新
  • linux怎么使用ping命令
  • win7系统为什么玩不了游戏
  • icloud怎么加密码
  • 怎样把系统及软件迁移到固态
  • 微软反盗xp黑屏怎么办
  • iphone服务器
  • PACKAGER.EXE - PACKAGER是什么进程 有什么用
  • win8命令提示符怎么运行命令
  • win7系统删除密码
  • linux中切换目录命令符
  • xp系统explorer停止工作
  • nodejs json数据库
  • 在批改中,可以使用x表示错误
  • 增值税发票综合服务平台登录不了
  • 红字发票税务局不愿意退税怎么处理
  • 已经交完费还可以用医保卡报销吗
  • 云南国税局官网网站
  • 债务核销条件
  • 耕地占用税减免支持项目发展
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设