>  기사  >  웹 프론트엔드  >  Redux Hooks 사용에 대한 세부 사항을 설명하는 기사

Redux Hooks 사용에 대한 세부 사항을 설명하는 기사

青灯夜游
青灯夜游앞으로
2022-11-11 18:24:471463검색

이 글에서는 Redux Hooks 사용에 대해 자세히 설명하겠습니다. 모든 분들께 도움이 되기를 바랍니다!

Redux Hooks 사용에 대한 세부 사항을 설명하는 기사

Redux Hooks

Redux의 Hook 소개

이전 Redux 개발에서는 구성 요소를 Redux와 결합하기 위해 React-redux 라이브러리에서 연결을 사용했습니다.

그러나 , 이 방법은 반환된 고차 구성요소와 결합된 고차 함수를 사용해야 하며

다음을 작성해야 합니다: mapStateToProps 및 mapDispatchToProps 매핑 함수. 구체적인 사용법은 이전 문서에 설명되어 있습니다. 프로그래밍 영상

Redux7.1부터는 Hook 메소드를 제공하며, 함수 컴포넌트에 해당 매핑 함수를 작성할 필요가 없습니다.

useSelector를 사용하여 전송합니다. state Map to the component

: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 &#39;react&#39;
import { useDispatch, useSelector } from &#39;react-redux&#39;
import { changeMessageAction, changeNumberAction } from &#39;./store/modules/counter&#39;

// 子组件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

매개변수 1: 콜백 함수를 전달해야 하며 상태는 콜백 함수에 전달되며 콜백 함수의 반환 값은 객체여야 합니다. 객체에 사용할 데이터를 작성할 수 있습니다. 반환된 객체를 직접 분해하여 사용하려는 상태의 데이터를 가져올 수 있습니다
import React, { memo } from &#39;react&#39;
import { useDispatch, useSelector, shallowEqual } from &#39;react-redux&#39;
import { changeMessageAction, changeNumberAction } from &#39;./store/modules/counter&#39;

// 子组件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

매개변수 2: 구성 요소가 다시 렌더링되는지 비교하여 확인할 수 있습니다.

🎜 useSelector는 기본적으로 반환된 두 개체를 비교합니다. Equality🎜;🎜🎜🎜어떻게 비교할 수 있나요?🎜
  • useSelector의 두 번째 매개변수에서 shallowEqual 함수를 전달합니다. 비교를 위한 React-redux 라이브러리 li>
rrreee🎜 즉, 다시 렌더링을 피하기 위해 완전히 동일한 두 객체를 반환해야 합니다. 🎜🎜🎜🎜useDispatch는 매우 간단합니다. useDispatch Hook을 호출하면 디스패치 함수를 직접 가져오고 컴포넌트에서 직접 사용할 수 있습니다🎜;🎜rrreee🎜useStore를 통해 현재 저장소 객체를 가져올 수도 있습니다. (그냥 이해하세요. 직접 작업하는 것은 권장하지 않습니다.) store 객체);🎜
🎜🎜🎜Using Hooks in Redux🎜🎜🎜 Redux의 Hooks를 사용하여 App 컴포넌트에 카운터를 구현하고, 앱의 하위 구성 요소:🎜🎜🎜먼저 간단한 저장소를 만듭니다🎜🎜rrreeerrreee🎜🎜react-redux 라이브러리를 사용하려면 Provider를 가져와 앱 구성 요소를 래핑해야 합니다🎜🎜rrreee🎜🎜useSelector 및 useDispatch를 사용합니다. 스토어의 데이터를 얻고 수정하는 작업을 수행하는 컴포넌트🎜🎜rrreee🎜 🎜이제 스토어의 데이터를 컴포넌트에서 사용하고 수정했지만 여전히 작은 문제가 있습니다(성능 최적화 em>)🎜🎜🎜🎜App 컴포넌트에서 카운터를 수정하면 App 컴포넌트가 다시 렌더링되는 것은 문제가 되지 않습니다. 그러나 Home 컴포넌트는 메시지를 사용하고 카운터를 사용하지 않지만, 마찬가지로 홈 하위 구성 요소에서 메시지가 수정되면 루트 구성 요소인 앱도 다시 렌더링됩니다. 이는 기본적으로 useSelector가 전체 상태를 수신하기 때문에 상태가 변경될 때 이 문제를 해결하려면 useSelector의 두 번째 매개변수를 사용하여 다시 렌더링이 필요한지 여부를 제어해야 합니다. shallowEqual만 전달하면 됩니다. 내부적으로 얕은 비교를 자동으로 수행합니다. 사용된 상태의 데이터가 변경된 경우에만 다시 렌더링됩니다🎜🎜rrreee 🎜더 많은 프로그래밍 관련 지식을 보려면 다음을 방문하세요. 🎜프로그래밍 교육 🎜! ! 🎜

위 내용은 Redux Hooks 사용에 대한 세부 사항을 설명하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제