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

  • 试玩游戏需要注意的技巧(游戏试玩怎么样)

    试玩游戏需要注意的技巧(游戏试玩怎么样)

  • oppo手机免打扰模式怎么取消(oppo手机免打扰模式别人打电话提示什么)

    oppo手机免打扰模式怎么取消(oppo手机免打扰模式别人打电话提示什么)

  • qq抽奖小程序在哪(qq抽奖小程序可以开挂吗)

    qq抽奖小程序在哪(qq抽奖小程序可以开挂吗)

  • 淘金币怎么兑换红包(淘金币怎么兑换话费)

    淘金币怎么兑换红包(淘金币怎么兑换话费)

  • 快手被限流了有提示吗(快手被限流了有通知吗)

    快手被限流了有提示吗(快手被限流了有通知吗)

  • 如何查找陌生微信群(怎么查陌生微信号)

    如何查找陌生微信群(怎么查陌生微信号)

  • 百分之符号怎么打(百分号的符号怎么打)

    百分之符号怎么打(百分号的符号怎么打)

  • internet使用的协议是什么(internet采用的协议类型为)

    internet使用的协议是什么(internet采用的协议类型为)

  • 仅聊天可以看到对方朋友圈吗(仅聊天可以看到对方给共同好友点赞吗)

    仅聊天可以看到对方朋友圈吗(仅聊天可以看到对方给共同好友点赞吗)

  • 苹果手机喜马拉雅下载的音频在哪里(苹果手机喜马拉雅音频怎么导出mp3)

    苹果手机喜马拉雅下载的音频在哪里(苹果手机喜马拉雅音频怎么导出mp3)

  • qq群解散后还能看到之前发的消息么(qq群解散后还能发消息吗)

    qq群解散后还能看到之前发的消息么(qq群解散后还能发消息吗)

  • 微信新朋友过期了,要怎么才能加(微信新朋友过期是按什么顺序来的呀)

    微信新朋友过期了,要怎么才能加(微信新朋友过期是按什么顺序来的呀)

  • mate10pro64g和128g区别

    mate10pro64g和128g区别

  • 电脑上ent是哪个键(enc是什么牌子电脑)

    电脑上ent是哪个键(enc是什么牌子电脑)

  • vivos1pro耗电快怎么办(vivos1pro耗电快怎么回事)

    vivos1pro耗电快怎么办(vivos1pro耗电快怎么回事)

  • 好看视频提现安全吗(好看视频提现安全不)

    好看视频提现安全吗(好看视频提现安全不)

  • iPhone Xs Max的机身容量有几种(iPhone xs max的机身尺寸)

    iPhone Xs Max的机身容量有几种(iPhone xs max的机身尺寸)

  • 安卓手机备忘录在哪里打开(安卓手机备忘录可以扫描文件吗)

    安卓手机备忘录在哪里打开(安卓手机备忘录可以扫描文件吗)

  • 50m宽带用什么路由器(50m宽带要用什么路由器)

    50m宽带用什么路由器(50m宽带要用什么路由器)

  • vivoz5x返回键怎么设置(vivoz5i手机怎么设置返回键在屏幕上)

    vivoz5x返回键怎么设置(vivoz5i手机怎么设置返回键在屏幕上)

  • 苹果x怎么取消屏幕旋转方法(苹果x怎么取消订阅的付费项目)

    苹果x怎么取消屏幕旋转方法(苹果x怎么取消订阅的付费项目)

  • 苹果Mac系统遇到蓝牙文件传输失败不支持的项该怎么办?(mac电脑遇到问题而重新启动)

    苹果Mac系统遇到蓝牙文件传输失败不支持的项该怎么办?(mac电脑遇到问题而重新启动)

  • Yarn 配置管理(yarn的配置)

    Yarn 配置管理(yarn的配置)

  • wordpress更新文章后总是向文章内连接发送GET请求(wordpress最新版本)

    wordpress更新文章后总是向文章内连接发送GET请求(wordpress最新版本)

  • 【chatgpt】chatgpt使用Api教程不使用科学方法(chat top)

    【chatgpt】chatgpt使用Api教程不使用科学方法(chat top)

  • 查补以前年度税款
  • 预缴税款计算公式
  • 个体户每个月要申报个税吗
  • 房屋契税怎么交在手机上操作
  • 应付账款及预付账款分录
  • 印花税应计入什么账户
  • 新会计准则 预付房租怎么做账
  • 个税属于会计中的什么科目
  • 生产成本存货会计分录
  • 挂失申请怎么写
  • 行政划拨无偿取得发票
  • 外经证预缴附加税
  • 冲减产品成本会计分录
  • 公司补贴为什么要交税
  • 营改增后增值税小规模纳税人按什么申报
  • 通用机打发票单位名称打不下怎么办
  • 完税凭证是什么
  • 增值税附表三怎么填 举例说明
  • 印花税可以计入开办费吗
  • 产品检测费用计入什么科目
  • 员工个人所得税申报方式选哪个
  • 赔偿款和罚款是一样的吗
  • 长期股权投资的投资收益怎么算
  • 母公司代发工资如何处理
  • 当月费用下月付款
  • mac怎么创建热点
  • 汇算清缴中的科目怎么填
  • mac怎么访问路径
  • php基于反射机制实验报告
  • php双冒号和箭头
  • win7如何调出浏览器
  • 土地使用税的税目写什么
  • 2021最好的固态
  • 土地增值税清算管理规程
  • 库存现金总分类账怎么登记
  • php session实例
  • 利用python实现Apriori关联规则算法
  • 预提费用的会计分录2018
  • 运输途中发生的费用
  • 住宿费补贴
  • 企业其他应付款余额非常大的原因
  • java 读写锁 map
  • 织梦设置会员访问
  • 更改sql server数据库名
  • 交易性金融资产是什么意思
  • 计提加计抵减额在财务报表里哪里体现
  • 一般纳税人差额纳税
  • 残保金 滞纳金
  • 银行利息怎么算10万块三年多少利息
  • 残保金是计入管理费用还是?
  • 应收账款损失率计算公式
  • 盘亏的主要原因是什么
  • 水费差额缴税如何计算
  • 长期待摊费用多少金额
  • 公司开业前期费用谁出
  • 福利费可以不走应付职工薪酬吗
  • 进口向海关缴纳消费税
  • 民办非企业单位什么意思
  • 微信收款计入现金流量吗
  • 普通发票记账联盖章了怎么办
  • 水费发票上的册子是什么
  • ie8 开发者工具
  • tcpsyncookies
  • linux详解
  • XP系统怎么设置屏幕常亮
  • 删除xp本地保存的视频
  • centos7文件路径
  • 查看电脑是否可以装两个固态
  • win7怎么cmd
  • 实现原生的ajax
  • shell脚本用法
  • 自制u盘杀手
  • 衬线字体和无衬线字体各自的用途
  • bat批处理文件的语句
  • 详解JavaScript对W3C DOM模版的支持情况
  • 安卓自定义状态栏图标
  • jquery中的each方法
  • 江苏省国税电子税务局官网发票验
  • 江苏国税电子税务局网上申报流程
  • 税务鉴定收费标准
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设