最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

redux中的hooks使用詳解

 更新時間:2025年07月29日 08:57:26   作者:改了一個昵稱  
useSelector從Redux提取狀態(tài),配合shallowEqual和memo優(yōu)化渲染性能;Reselect通過緩存減少重復計算,適用于復雜選擇器邏輯,提升效率

useSelector

基礎使用

  • 功能:useSelector 是 react-redux 提供的 Hook,用于從 Redux Store 中選擇(提取)狀態(tài)數(shù)據
  • 參數(shù)一:接收一個 選擇器函數(shù),該函數(shù)接收完整的 Redux Store 狀態(tài)(state)作為參數(shù),返回需要的數(shù)據
  • 參數(shù)二: 可傳入shallowEqual,比較來決定組件是否重新渲染
  • 返回值:返回 選擇器函數(shù)的結果(這里是 { count: … } 對象)
import { useSelector } from 'react-redux'
import { memo } from 'react'

const App = memo(() => {
	` 使用 useSelector 將 Redux Store 中的數(shù)據映射到組件內 `
	` state 參數(shù):代表整個 Redux Store 的根狀態(tài)(root state) `
	const { count } = useSelector((state) => {
		return {
			`假設你的 Redux Store 中有一個名為 counter 的 slice(分片),該 slice 的狀態(tài)中包含 count 字段`
			count: state.counter.count
		}
	})

	return (
		<div>
			<h2>count: {count}</h2>
		</div>
	)
})

這里memo的作用:

  • 用于對組件進行淺層 props 比較,避免不必要的重新渲染。

適用場景:

  • 如果 App 組件的父組件頻繁渲染,但 App 的 props 未變化,memo 可以優(yōu)化性能。

memo 與 useSelector 的關系:

  • 即使 memo 包裹了組件,useSelector 仍會在 Redux Store 的 count 變化時觸發(fā)組件更新(因為內部狀態(tài)變化)。

第二個參數(shù) shallowEqual

  • 功能:shallowEqual 是 react-redux 提供的淺比較函數(shù),用于,比較兩次選擇器返回的結果,是否 “淺層相等” 。
  • 適用場景:當你的選擇器返回一個對象或數(shù)組時,shallowEqual 會逐個比較對象的每個屬性(或數(shù)組的每個元素)是否嚴格相等(===)。
  • 深層嵌套無效:shallowEqual 僅比較 第一層屬性。如果對象有深層嵌套(如 { data: { count: 1 } }),深層變化不會被檢測到。

父組件修改count時,App依賴的count發(fā)生改變,所以,父組件App會重新渲染,

但是,此時子組件也重新渲染了,子組件并沒有依賴count,而且子組件此時是用memo包裹的,memo包裹的組件只有當其props發(fā)生改變時,才會重新渲染。

當子組件修改msg時,App組件也重新渲染了。

這是因為使用了useSelector,useSelector 監(jiān)聽的是 整個state數(shù)據,如果state里有任何數(shù)據發(fā)生變化,當前組件就會重新渲染。

而正常情況下,應該是:

  • 只有 msg 改變時,子組件才會渲染;
  • 只有count改變時,父組件才會渲染。

useSelector的第二個參數(shù):用來比較來決定組件是否需要渲染,當state發(fā)生改變時,useSelector 將本次映射的值與上次映射的值有沒有發(fā)生改變,有改變則重新渲染,沒有改變則不變。

// state發(fā)生變化時,父組件的useSelector判斷本次映射的count與上次映射的count是否一致,不一致則重新渲染,否則不重新渲染
const { count } = useSelector((state) => {
	return {
		count: state.counter.count
	}
}, shallowEqual)

// state發(fā)生變化時,子組件的useSelector判斷本次映射的msg與上次映射的msg是否一致,不一致則重新渲染,否則不重新渲染
const { msg } = useSelector((state) => {
	return {
		msg: state.counter.msg
	}
}, shallowEqual)

Reselect

Reselect 是一個專為 Redux 設計的記憶化選擇器庫,用于優(yōu)化從 Redux Store 中提取數(shù)據的性能。

它的核心思想是:通過緩存(memoization)避免重復計算,確保只有在相關狀態(tài)變化時,才重新執(zhí)行選擇器邏輯。

(1) 什么是記憶化(Memoization)?

  • 定義:記憶化是一種優(yōu)化技術,用于緩存函數(shù)的輸入和輸出。當函數(shù)以相同的輸入再次調用時,直接返回緩存的結果,而不是重新計算。
  • 目的:在 Redux 中,當狀態(tài)頻繁變化但某些派生數(shù)據未變化時,避免重復計算這些派生數(shù)據,從而提升性能。

(2) Reselect 的作用

場景

  • 當你的選擇器邏輯復雜(如:組合`個狀態(tài)片段、進行計算)時,Reselect 會自動緩存結果。

優(yōu)勢

  • 減少不必要的計算。
  • 確保組件只在相關狀態(tài)變化時重新渲染。
  • 保持選擇器邏輯的純凈(無副作用)。

Reselect 的核心 API:createSelector

用法:

import { createSelector } from 'reselect'

`輸入選擇器:從狀態(tài)中提取原始數(shù)據`
const selectUser = (state) => state.user       【state.user 是 Redux Store 中的一個 slice】
const selectPosts = (state) => state.posts     【state.posts 是 Redux Store 中的一個 slice】

`Reselect 的 createSelector 會按順序將 輸入選擇器的返回值,作為參數(shù)傳遞給轉換函數(shù)。
 因此,轉換函數(shù)中的
   user  對應 selectUser的返回值(即state.user)
   posts 對應 selectPosts的返回值(即state.posts)`
const selectUserData = createSelector(
	[selectUser, selectPosts],    `【輸入選擇器數(shù)組】`
	(user, posts) => ({           `【轉換函數(shù)】`
		username: user.name,
		postCount: posts.length,
	})
)

某組件如下:

import { useSelector } from 'react-redux'
import { selectUserData } from './selectors'

const Component = () => {
	const { username, postCount } = useSelector(selectUserData)
	
	return (
		<div>
			<h3>{username}</h3>
			<p>Posts: {postCount}</p>
		</div>
	)
}
  • Reselect 的緩存機制
  • 緩存觸發(fā)條件:只有當 selectUserselectPosts 的返回值變化時,轉換函數(shù)才會重新執(zhí)行。

執(zhí)行流程:

首次調用

  • 執(zhí)行所有輸入選擇器(selectUserselectPosts)。
  • 將結果傳遞給轉換函數(shù),計算并緩存最終值。

后續(xù)調用

  • 再次執(zhí)行輸入選擇器。
  • 如果所有輸入選擇器的結果與上一次相同(嚴格相等 ===),直接返回緩存值。
  • 否則,重新執(zhí)行轉換函數(shù)并更新緩存。

結合shallowEqual

  • 如果選擇器返回對象,可以結合 shallowEqual 進一步優(yōu)化:
const { username, postCount } = useSelector(
	selectUserData,
	shallowEqual
)

高級用法:組合選擇器

多層選擇器

const selectUser = (state) => state.user
const selectPosts = (state) => state.posts

const selectUserData = createSelector(
	[selectUser, selectPosts],
	(user, posts) => ({
		username: user.name,
		postCount: posts.length,
	})
)

const selectUserStats = createSelector(
	[selectUserData],
	(userData) => ({
		avgPostsPerDay: userData.postCount / 30,
	})
)

帶參數(shù)的選擇器

const selectPostById = (postId) => createSelector(
	[(state) => state.posts],
	(posts) => posts.find(post => post.id === postId)
)

// 組件中使用
const Component = ({ postId }) => {
	const post = useSelector(() => selectPostById(postId))
	return <div>{post.title}</div>
}

深入解析:Reselect 的工作原理

(1) 輸入選擇器的順序

輸入選擇器的順序會影響緩存鍵的計算。例如:

const selectorA = createSelector(
  [selectX, selectY],
  (x, y) => x + y
);

const selectorB = createSelector(
  [selectY, selectX],
  (y, x) => y + x
);
  • selectorAselectorB 的緩存鍵不同(順序不同),即使邏輯相同也會重新計算。

(2) 緩存的生命周期

  • 全局緩存:Reselect 的緩存是全局的,與組件實例無關。
  • 狀態(tài)變化時:只要輸入選擇器的結果變化,緩存就會失效。

(3) 深層嵌套狀態(tài)的處理

  • 如果狀態(tài)是深層嵌套的對象,輸入選擇器需要提取具體的字段:
const selectDeepData = createSelector(
  [(state) => state.deep.nested.data],
  (data) => data.value
);

總結:

Reselect 的本質:通過記憶化選擇器,避免重復計算,優(yōu)化性能。

適用場景:當選擇器邏輯復雜、依賴多個狀態(tài)片段或需要組合數(shù)據時。

最佳實踐

  • 優(yōu)先使用 createSelector 創(chuàng)建選擇器。
  • 保持輸入選擇器的簡單性,將復雜邏輯放在轉換函數(shù)中。
  • 結合 useSelectorshallowEqual 進一步優(yōu)化渲染性能。

useDispatch獲取dispatch函數(shù)

  • 直接用 useDispatch 獲取 dispatch ,派發(fā)action 即可
` 派發(fā)操作 `
const dispatch = useDispatch()

function calNumber (num) {
	dispatch(addNumberAction(num))
}

return (
	<div>
		<h2>count:{count}</h2>
		<button onClick={e => calNumber(1)}> +1 </button>
	</div>
)

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:

相關文章

  • React+Ts實現(xiàn)二次封裝組件

    React+Ts實現(xiàn)二次封裝組件

    本文主要介紹了React+Ts實現(xiàn)二次封裝組件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • React運行機制超詳細講解

    React運行機制超詳細講解

    React 作為當下最為流行的前端開發(fā)框架之一,使用它可以快速構建大型 Web 應用,加上其出色的性能表現(xiàn),使得眾多互聯(lián)網公司對它格外地青睞,這篇文章主要介紹了React運行機制
    2022-11-11
  • react實現(xiàn)動態(tài)表單

    react實現(xiàn)動態(tài)表單

    這篇文章主要為大家詳細介紹了react實現(xiàn)動態(tài)表單,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 淺談React Native Flexbox布局(小結)

    淺談React Native Flexbox布局(小結)

    這篇文章主要介紹了淺談React Native Flexbox布局(小結),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • react動態(tài)路由的實現(xiàn)示例

    react動態(tài)路由的實現(xiàn)示例

    React中動態(tài)路由通過ReactRouter庫實現(xiàn),根據應用狀態(tài)或用戶交互動態(tài)顯示或隱藏組件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-11-11
  • React組件的數(shù)據掛載實現(xiàn)方式

    React組件的數(shù)據掛載實現(xiàn)方式

    React中state為組件內部可變數(shù)據,通過setState更新;props為外部傳入的不可變參數(shù),兩者均可觸發(fā)渲染,但state由組件維護,props由父組件控制,列表需用key優(yōu)化性能,dangerouslySetInnerHTML用于內聯(lián)HTML
    2025-07-07
  • 在React中實現(xiàn)代碼熱重載(HMR)的操作步驟

    在React中實現(xiàn)代碼熱重載(HMR)的操作步驟

    在現(xiàn)代 React 開發(fā)中,代碼熱重載(HMR)是一項極大提升開發(fā)效率的技術,它允許在不刷新整個頁面的情況下,實時更新模塊代碼,從而保留應用狀態(tài),避免因頁面刷新導致的狀態(tài)丟失,本文將深入探討如何在 React 項目中實現(xiàn) HMR,包括其原理、配置步驟以及最佳實踐
    2025-05-05
  • 深入理解React Native原生模塊與JS模塊通信的幾種方式

    深入理解React Native原生模塊與JS模塊通信的幾種方式

    本篇文章主要介紹了深入理解React Native原生模塊與JS模塊通信的幾種方式,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07
  • React數(shù)據傳遞之組件內部通信的方法

    React數(shù)據傳遞之組件內部通信的方法

    這篇文章主要介紹了React數(shù)據傳遞之組件內部通信的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • React?Hooks項目實戰(zhàn)

    React?Hooks項目實戰(zhàn)

    React?Hooks是React?16.8版本引入的新特性,它使得在函數(shù)組件中也能夠使用狀態(tài)(state)和其他React特性,本文就來詳細介紹一下React?Hooks項目實戰(zhàn),感興趣的可以了解一下
    2023-11-11

最新評論

白水县| 宁武县| 舟曲县| 贵州省| 山丹县| 天台县| 宁强县| 昂仁县| 丰镇市| 西城区| 玉树县| 福海县| 汉川市| 从江县| 繁昌县| 沅陵县| 景宁| 平山县| 通州区| 班戈县| 常宁市| 兴国县| 济源市| 扬州市| 锡林郭勒盟| 当阳市| 大竹县| 武清区| 彭泽县| 大竹县| 青州市| 长宁区| 临澧县| 元朗区| 收藏| 九江县| 元谋县| 迁安市| 本溪市| 祁门县| 景德镇市|