React中Redux Hooks的使用详解

 更新时间:2023年07月08日 10:50:55   作者:学全栈的灌汤包  
这篇文章主要介绍了React Redux Hooks的使用详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

Redux Hooks

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
  }
})

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

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.js
import { 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.actions
export default counterSlice.reducer
// store/index.js
import { 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'
// 子组件Home
const 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>
  )
})
// 根组件App
const 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'
// 子组件Home
const 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>
  )
})
// 根组件App
const 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

到此这篇关于React - Redux Hooks的使用细节详解的文章就介绍到这了,更多相关React Redux Hooks使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解React中常见的三种路由处理方式选择

    详解React中常见的三种路由处理方式选择

    这篇文章主要为大家详细介绍了React中常见的三种路由处理方式该如何选择,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • react-router-dom V6的配置使用实践

    react-router-dom V6的配置使用实践

    本文主要介绍了react-router-dom V6的配置使用实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 基于React实现表单数据的添加和删除详解

    基于React实现表单数据的添加和删除详解

    这篇文章主要给大家介绍了基于React实现表单数据的添加和删除的方法,文中给出了详细的示例供大家参考,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。
    2017-03-03
  • react配置webpack-bundle-analyzer项目优化踩坑记录

    react配置webpack-bundle-analyzer项目优化踩坑记录

    这篇文章主要介绍了react配置webpack-bundle-analyzer项目优化踩坑记录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 解读react的onClick自动触发等相关问题

    解读react的onClick自动触发等相关问题

    这篇文章主要介绍了解读react的onClick自动触发等相关问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • react-native只保留3x图原理解析

    react-native只保留3x图原理解析

    这篇文章主要为大家介绍了react-native只保留3x图原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • React虚拟列表的实现

    React虚拟列表的实现

    在开发过程中,总是遇到很多列表的显示。当上数量级别的列表渲染于浏览器,终会导致浏览器的性能下降,你可以选择其他方式避免,本文就介绍了虚拟列表来解决这个问题
    2021-05-05
  • 解读useState第二个参数的"第二个参数"

    解读useState第二个参数的"第二个参数"

    这篇文章主要介绍了useState第二个参数的"第二个参数",具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • JavaScript中React面向组件编程(上)

    JavaScript中React面向组件编程(上)

    本文主要介绍了React组件中默认封装了很多属性,有的是提供给开发者操作的,其中有三个属性非常重要:state、props、refs。感兴趣的小伙伴可以参考阅读
    2023-03-03
  • React key值的作用和使用详解

    React key值的作用和使用详解

    这篇文章主要介绍了React key值的作用和使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08

最新评论