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

  • 鸿蒙系统只有华为手机可以用吗(鸿蒙系统只有华为能升级吗)

    鸿蒙系统只有华为手机可以用吗(鸿蒙系统只有华为能升级吗)

  • 儿童怎么生成行程卡(儿童怎么生成行车记录)

    儿童怎么生成行程卡(儿童怎么生成行车记录)

  • 小米10青春版是否有nfc功能(小米10青春版是什么处理器)

    小米10青春版是否有nfc功能(小米10青春版是什么处理器)

  • 三相负载根据什么原则作星形或三角形连接(三相负载根据什么条件作星型或三角连接)

    三相负载根据什么原则作星形或三角形连接(三相负载根据什么条件作星型或三角连接)

  • 手机怎样用乐播投屏到电视(手机怎样乐播投屏到电视)

    手机怎样用乐播投屏到电视(手机怎样乐播投屏到电视)

  • soulmate关系可以解除吗(soulmate关系有啥用)

    soulmate关系可以解除吗(soulmate关系有啥用)

  • 打12122怎么提示空号(12121为什么拨打不通)

    打12122怎么提示空号(12121为什么拨打不通)

  • 京东家庭号有什么用(京东家庭号有什么用能看到对方买了什么东西吗?)

    京东家庭号有什么用(京东家庭号有什么用能看到对方买了什么东西吗?)

  • 华为荣耀青春版怎么设置返回键(华为荣耀青春版30多少钱一台)

    华为荣耀青春版怎么设置返回键(华为荣耀青春版30多少钱一台)

  • 微信可以在别的手机上登录吗(微信可以在别的国家使用吗)

    微信可以在别的手机上登录吗(微信可以在别的国家使用吗)

  • 抖音关注打勾什么意思(抖音关注对勾)

    抖音关注打勾什么意思(抖音关注对勾)

  • 扩展名为ppt的文件类型是(ppt文件的扩展名为)

    扩展名为ppt的文件类型是(ppt文件的扩展名为)

  • ios10什么时候发布的(ios10发布时间)

    ios10什么时候发布的(ios10发布时间)

  • nova6可以无线充电吗(nova6能否无线充电)

    nova6可以无线充电吗(nova6能否无线充电)

  • 华为mate30pro支持北斗导航吗(华为mate30pro支持广电网络吗)

    华为mate30pro支持北斗导航吗(华为mate30pro支持广电网络吗)

  • 拼多多月卡每月都扣费吗(拼多多月卡每月使用试用机会)

    拼多多月卡每月都扣费吗(拼多多月卡每月使用试用机会)

  • 京东碎屏保有用吗(京东碎屏保有用吗安全吗)

    京东碎屏保有用吗(京东碎屏保有用吗安全吗)

  • iphone11怎么从安卓手机转移数据(苹果11怎么从安卓导入数据)

    iphone11怎么从安卓手机转移数据(苹果11怎么从安卓导入数据)

  • iphone11是高通基带吗(苹果11用的高通基带吗)

    iphone11是高通基带吗(苹果11用的高通基带吗)

  • 趣步注销了还能恢复吗(趣步注销了还能用吗)

    趣步注销了还能恢复吗(趣步注销了还能用吗)

  • 拼多多好友误删怎样加回来(拼多多好友删了)

    拼多多好友误删怎样加回来(拼多多好友删了)

  • 智能侧边栏怎么换位置(智能侧边栏怎么打开)

    智能侧边栏怎么换位置(智能侧边栏怎么打开)

  • 苹果手机更换电池在保修范围内吗(苹果手机更换电池后不显示健康值)

    苹果手机更换电池在保修范围内吗(苹果手机更换电池后不显示健康值)

  • Js各种时间转换问题(YYYY-MM-DD 时间戳 中国标准时间)(js时间格式转换时间戳)

    Js各种时间转换问题(YYYY-MM-DD 时间戳 中国标准时间)(js时间格式转换时间戳)

  • 调制解调器的作用是详细介绍(调制解调器的作用包括)

    调制解调器的作用是详细介绍(调制解调器的作用包括)

  • 服务费收入是什么
  • 房产税的计算公式是多少
  • 发生租赁费用怎么做账
  • 采购人员的费用
  • 企业所得税固定资产
  • 什么企业不用交社保
  • 税负率是含税还是不含税
  • 服务类公司没有营业执照
  • 建筑服务适用简易计税吗
  • 已发货未收款怎么做会计分录
  • 商业地产运营成本核算
  • 机动车销售统一专票有几联
  • 监督审核费用会计入账
  • 销售返利计入什么科目
  • 政府给的专款专用发票
  • 免税企业开了含税发票
  • 股票收入要交所得税吗
  • 税务局领普通发票需要多少钱
  • 商贸企业发出商品
  • 进项构成比例是啥
  • 向境外企业支付服务费代扣代缴什么税
  • 企业增资需要缴纳什么税
  • 苹果键盘快捷键怎么用
  • 单位社保部分会扣吗
  • 在Win7系统中,文件的属性包括
  • 公司购买基金怎样入账
  • win7宽带连接错误651
  • 如何使用定向流量
  • 调整之前的凭证怎么删除
  • 处理车辆违章送哪个部门
  • 中秋节给员工购物文案
  • 前端文件预览
  • 户外广告位怎么收费
  • php imagick
  • 转让专利权的会计处理结果
  • 损益类科目包括利润分配吗
  • 负债大于资产是逆差还是顺差
  • vue基础知识
  • framework core
  • python 构建
  • thinkphpgui
  • linux mput命令
  • 注册资本实缴后可以减资吗
  • 汉诺塔问题动画演示
  • mysql 5.7特性
  • 发放工资代扣个人所得税的记账凭证怎么填
  • 计提租金如何做账务处理
  • 机械租赁公司挂牌流程
  • 劳动保护费进什么科目
  • 扶贫差旅费
  • 短期理财收益账务分录
  • 转账支票的密码需要填写吗
  • 按揭贷款汽车会被抵押吗
  • sql查询从入门到实践
  • win10系统详情
  • windows server 2008 日志文件在哪
  • gitlab linux
  • 正确安全管理操作手册
  • 彻底关闭windows10自动更新工具
  • 在linux中使用哪个命令可以用于管理用户账户
  • u盘安装win7系统教程图解
  • linux中ls命令的功能
  • linux 中的MYSQL命令汇总 适合学习linux下配置mysql的朋友
  • win8怎么设置桌面
  • win10怎么添加蓝牙驱动
  • gzip: stdin: unexpected end of file tar: Unexpected EOF in archive tar: Unexpect
  • win7系统开机黑屏自检
  • Win10年度升级版Redstone来了:更加个人化的计算体验
  • 怎么做小地图图片呢
  • 深入理解javascript特性.pdf
  • typeof的缺点
  • 遮罩层 css
  • unity3d winform
  • JavaScript中setUTCFullYear()方法的使用简介
  • js 原型继承的几种方法
  • 自然人扣缴端初始密码
  • 购置税完税证明在哪里打印
  • 账本遗失征管法处罚
  • 矿产资源税税率2020年
  • 企业分立需要开发票吗?
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设