Redux,React-redux。基礎

狀態管理庫,集中式存儲狀態,管理狀態

? redux

在這里插入圖片描述

//簡單實現 redux源碼
export function createStore(reducer) {// reducer由用戶編寫, 必須是一個函數,dispatch的時候,reducer要執行if (typeof reducer !== 'function') throw new Error('reducer必須是一個函數')let state // 公共狀態let listeners = [] //事件池// 1.獲取公共狀態  store.getState()const getState = () => {return state}// 2.組件更新方法 進入事件池const subscribe = listener => {if (typeof listener !== 'function') throw new Error('listener 必須是一個函數')// 去重,防止重復添加if (!listeners.includes(listener)) {// 讓組件更新的方法進入事件池listeners.push(listener)}// 返回一個函數,用于從事件池中刪除對應的方法 (取消訂閱)return function unsubscribe() {// 找到事件池中的對應方法,并刪除listeners = listeners.filter(l => l !== listener)}}// 3.派發任務通知 Reducer 執行const dispatch = action => {// 必須是對象if (typeof action !== 'object') throw new Error('action 必須是一個對象')// 必須有 type 屬性if (typeof action.type === 'undefined') throw new Error('action 必須有 type 屬性')// 執行 reducer,參數為當前 state 和 action動作,返回新的 stateconst nextState = reducer(state, action)// 更新 公共狀態state = nextState// 通知事件池中的方法,更新組件for (let i = 0; i < listeners.length; i++) {const listener = listeners[i]listener()}}// 4.redux初始化statedispatch({ type: '@@redux/INIT' })// 5. 返回 store 對象 { getState, dispatch, subscribe }return {getState,dispatch,subscribe}
}

1. 重要概念

狀態是只讀的,
后續修改狀態的方式是通過Reducer(純函數)接收舊狀態和 Action,返回新狀態。
Reducer無副作用,同樣的輸入必然得到同樣的輸出。

2. 數據流

  1. 組件通過 dispatch(action) 發送 Action。
  2. Redux 調用對應的 Reducer,生成新狀態。
  3. Store 更新狀態,通知所有訂閱了 Store 的組件。
  4. 組件通過 getState() 獲取新狀態并重新渲染。

問:Store 更新狀態,如何通知組件更新?
通過Store內部的Subscription(listener)方法,listener 通常是 ?觸發組件重新渲染的函數,或是 ?與組件更新相關的副作用邏輯。見下:

  1. 類組件:listener 通常是調用 this.forceUpdate() 的函數,強制組件重新渲染。
class Counter extends React.Component {componentDidMount() {// 定義 listener:強制組件重新渲染this.unsubscribe = store.subscribe(() => {this.forceUpdate();});}componentWillUnmount() {this.unsubscribe(); // 取消訂閱}render() {const count = store.getState().count;return <div>{count}</div>;}
}
  1. 函數組件:listener 是 useState 的 副作用函數
import React, { useState, useEffect } from 'react';
import store from './store';function Counter() {// 定義forceUpdate 單純是為了觸發組件渲染更新,屬性無意義 const [_, forceUpdate] = useState(0);  useEffect(() => {// 定義 listener:強制組件重新渲染const unsubscribe = store.subscribe(() => {forceUpdate(prev => prev + 1);});return unsubscribe; // useEffect 清理函數中取消訂閱}, []);const count = store.getState().count;return <div>{count}</div>;
}
  1. 使用 react-redux 的 connect: connect 高階組件內部會處理訂閱邏輯,listener 是?比較新舊 props 并決定是否更新組件的函數。
    connect 是 高階函數,內部會將公共狀態以props的方式傳遞給組件。
import { connect } from 'react-redux';class Counter extends React.Component {render() {return <div>{this.props.count}</div>;}
}// 映射狀態到 props
const mapStateToProps = (state) => ({count: state.count,
});// connect 內部邏輯(簡化):
// 1.  Store的監聽器會比較新舊 mapStateToProps 的結果。
// 2. 若結果變化,觸發組件更新。
export default connect(mapStateToProps)(Counter);
  1. react-redux 的 useSelector鉤子
    useSelector 的 listener 是 ?檢查選擇器返回值是否變化,并觸發重新渲染 的函數。
import { useSelector } from 'react-redux';function Counter() {// 內部實現(簡化):// 1. 訂閱 Store,監聽器會比較新舊 selector(state) 的結果。// 2. 若結果變化,觸發組件重新渲染。const count = useSelector((state) => state.count);return <div>{count}</div>;
}

?????? React-Redux

對redux 進行了包裝。

  1. <Provider> 組件:Redux Store 注入整個 React 應用,使所有子組件可以訪問 Store。
  2. usSelector Hook:從 Store 中獲取狀態,并自動訂閱狀態更新,當狀態變化時,若返回的值與之前不同,組件會重新渲染。
  3. useDispatch Hook:獲取 dispatch 方法,派發 Action
  4. connect 高階組件(類組件兼容):。
import { connect } from 'react-redux';
import { increment, decrement } from './actions';class Counter extends React.Component {render() {const { count, increment, decrement } = this.props;return (<div><button onClick={decrement}>-</button><span>{count}</span><button onClick={increment}>+</button></div>);}
}// 映射 State 到 Counter的 props,以供取值
const mapStateToProps = (state) => ({count: state.count,
});// 映射 dispatch 到 Counter的 props,以供調用
const mapDispatchToProps = {increment,decrement,
};export default connect(mapStateToProps, mapDispatchToProps)(Counter);

connect :同 useSelector作用一樣,為了訪問 redux的store

但是這個比較繞一點(兼容了類組件)

  • 輸入:一個 React 組件(類 or FC)
  • 輸出:一個新的組件,該組件能訪問 Redux store
// 模擬 react-redux 的 connect 函數
const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {return class Connect extends React.Component {static contextType = ReactReduxContext; // 從 Provider 獲取 storeconstructor(props, context) {super(props);this.store = context.store;this.state = {mappedProps: this.calculateProps()};}componentDidMount() {this.unsubscribe = this.store.subscribe(() => {const newMappedProps = this.calculateProps();// 淺比較優化,避免不必要的渲染if (!shallowEqual(this.state.mappedProps, newMappedProps)) {this.setState({ mappedProps: newMappedProps });}});}componentWillUnmount() {this.unsubscribe();}calculateProps() {const state = this.store.getState();const stateProps = mapStateToProps(state);const dispatchProps = mapDispatchToProps(this.store.dispatch);return { ...stateProps, ...dispatchProps };}render() {return <WrappedComponent {...this.props} {...this.state.mappedProps} />;}};
};

combineReducers

組合多個獨立 reducer 的核心工具函數

  • 自動分發 Action:
    當一個 action 被 dispatch 時,combineReducers 會 ?自動將該 action 傳遞給所有子 reducer
import { combineReducers } from 'redux'import FatherAndSonReducer from './FatherAndSonReducer'
import TaskReducer from './TaskReducer'const rootReducer = combineReducers({FatherAndSonReducer,TaskReducer
})export default rootReducer

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74438.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74438.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74438.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

5.2 位運算專題:LeetCode 268. 丟失的數字

1. 題目鏈接 LeetCode 268. 丟失的數字 2. 題目描述 給定一個包含 [0, n] 范圍內 n 個不同整數的數組 nums&#xff08;實際長度為 n&#xff09;&#xff0c;找出數組中缺失的那個數字。 示例&#xff1a; 輸入&#xff1a;nums [3,0,1] → 輸出&#xff1a;2&#xff08;…

基于第三方庫的人臉識別系統的設計與實現

標題:基于第三方庫的人臉識別系統的設計與實現 內容:1.摘要 本文針對傳統人臉識別系統開發復雜、效率低的問題&#xff0c;旨在設計并實現基于第三方庫的人臉識別系統。通過選用合適的第三方人臉識別庫&#xff0c;利用其成熟的算法和接口&#xff0c;簡化系統開發流程。對收集…

【Android】VehiclePropertyAccess引起CarService崩潰

VehiclePropertyAccess引起CarService崩潰 VehiclePropertyAccess VehiclePropertyAccess屬性&#xff0c;用于定義車輛屬性的訪問權限。權限包括 讀&#xff1a;READ&#xff0c;只可以讀取&#xff0c;不能寫入。 VehiclePropertyAccess:READ寫&#xff1a;WRITE&#xf…

【Go】Go語言并發模型:MPG

Go 語言并發模型&#xff1a;MPG Go 的并發模型主要由三個部分構成&#xff1a; M (Machine) 系統線程&#xff0c;用于實際執行任務。 P (Processor) 邏輯處理器&#xff0c;負責管理和調度 goroutine。每個 P 擁有一個本地隊列和關聯的全局 G 隊列。 G (Goroutine) Go 語言…

SpringCloud配置中心:Config Server與配置刷新機制

文章目錄 引言一、Config Server基礎架構1.1 Server端配置1.2 配置文件命名規則 二、Config Client配置2.1 Client端配置2.2 配置注入與使用 三、配置刷新機制3.1 手動刷新配置3.2 使用Spring Cloud Bus實現自動刷新3.3 配置倉庫Webhook自動觸發刷新 四、高級配置管理策略4.1 配…

PyTorch生成式人工智能實戰:從零打造創意引擎

PyTorch生成式人工智能實戰&#xff1a;從零打造創意引擎 0. 前言1. 生成式人工智能1.1 生成式人工智能簡介1.2 生成式人工智能技術 2. Python 與 PyTorch2.1 Python 編程語言2.2 PyTorch 深度學習庫 3. 生成對抗網絡3.1 生成對抗網絡概述3.2 生成對抗網絡應用 4. Transformer4…

allure結合pytest生成測試報告

結合 pytest 和 Allure 可以生成詳細而美觀的測試報告&#xff0c;幫助測試人員和開發者更好地理解測試結果。這包括測試的執行情況、步驟、附件&#xff08;如截圖&#xff09;、分類以及優先級標記。下面是如何在 pytest 中使用 Allure 生成測試報告的步驟&#xff1a; 安裝…

STM32標準庫開發中斷流程

在STM32標準外設庫&#xff08;SPL&#xff09;開發中&#xff0c;外設中斷的處理流程通常如下&#xff1a; 一、標準庫外設中斷處理流程 &#xff08;1&#xff09;使能外設時鐘 在使用任何外設之前&#xff0c;都必須打開外設的時鐘。例如&#xff0c;使用USART1的中斷&…

【計算機網絡】-計算機網絡期末復習題復習資料

一、計算機網絡體系結構&#xff08;800字&#xff09; 1. OSI參考模型 七層結構&#xff1a;物理層→數據鏈路層→網絡層→傳輸層→會話層→表示層→應用層 各層核心功能&#xff1a; 物理層&#xff1a;比特流傳輸&#xff08;如RJ45、光纖接口&#xff09; 數據鏈路層&…

31天Python入門——第9天:再學函數

你好&#xff0c;我是安然無虞。 文章目錄 再學函數1. 變量在函數中的作用域2. 函數的參數傳遞.補充學習: 不定長參數*args和**kwargs 3. 值傳遞和引用傳遞補充學習: 把函數作為參數傳遞 4. 匿名函數5. python中內置的常用函數zip()map()filter()all()any() 6. 函數練習 再學函…

EasyUI數據表格中嵌入下拉框

效果 代碼 $(function () {// 標記當前正在編輯的行var editorIndex -1;var data [{code: 1,name: 1,price: 1,status: 0},{code: 2,name: 2,price: 2,status: 1}]$(#dg).datagrid({data: data,onDblClickCell:function (index, field, value) {var dg $(this);if(field ! …

【C語言】多進程/多線程

【C語言】多進程/多線程 參考鏈接多進程/多線程服務器1. 多進程服務器2. 多線程服務器 結語參考鏈接 參考鏈接 c 中文網 菜鳥 c 多進程/多線程服務器 多進程和多線程是常用的并發編程技術。它們都允許程序同時執行多個任務&#xff0c;提高了系統的資源利用率和程序的運行效率…

mysql 磐維(opengauss)tidb誤刪數據之高級恢復

Mysql參考&#xff1a; Mysql 8.0 XtraBackupMysqlbinlog 完全恢復 - 墨天輪 Mysql 8.0 XtraBackupMysqlbinlog 完全恢復[TOC]# 一、安裝mysql 8.0.19## 1.1https://www.modb.pro/db/509223MySQL 的全量備份、增量備份與 Binlog 時間點恢復_mysqlbinlog自動備份嗎-CSDN博客文章…

3. 軸指令(omron 機器自動化控制器)——>MC_SetPosition

機器自動化控制器——第三章 軸指令 11 MC_SetPosition變量?輸入變量?輸出變量?輸入輸出變量 功能說明?時序圖?重啟動運動指令?多重啟運動指令?異常 MC_SetPosition 將軸的指令當前位置和反饋當前位置變更為任意值。 指令名稱FB/FUN圖形表現ST表現MC_SetPosition當前位…

從 @SpringBootApplication 出發,深度剖析 Spring Boot 自動裝配原理

在 Spring Boot 的開發旅程中&#xff0c;SpringBootApplication 注解堪稱開啟便捷開發之門的鑰匙。它不僅是一個簡單的注解&#xff0c;更是理解 Spring Boot 自動裝配原理的重要入口。接下來&#xff0c;我們將以SpringBootApplication 為切入點&#xff0c;深入探究 Spring …

MySQL面試專題

1.什么是BufferPool&#xff1f; Buffer Pool基本概念 Buffer Pool&#xff1a;緩沖池&#xff0c;簡稱BP。其作用是用來緩存表數據與索引數據&#xff0c;減少磁盤IO操作&#xff0c;提升效率。 Buffer Pool由緩存數據頁(Page) 和 對緩存數據頁進行描述的控制塊 組成, 控制…

調用百度api實現語音識別(python)

該代碼實現了一個企業級的語音識別解決方案,通過調用百度語音識別API,實現實時錄音識別和對已有音頻語音識別功能。 百度智能云:請自行訪問百度智能云,開通免費的語音識別功能,獲取API_KEY和SECRET_KEY。操作按照百度流程即可,可免費申請。 首先,配置下百度API和描述下錯…

KRaft模式

目錄標題 Kraft模式**1. 什么是Kraft模式&#xff1f;****2. 為什么引入Kraft模式&#xff1f;****3. 核心優勢****4. 架構與工作原理****5. 部署與配置要點****6. 適用場景與最佳實踐****總結**KIP-833: Mark KRaft as Production Ready除了Kraft模式&#xff0c;Kafka還有以下…

單片機電路中常見的英文術語及縮寫

以下是單片機電路中常見的英文術語及縮寫的解釋及其作用說明&#xff0c;按功能分類整理&#xff0c;便于理解&#xff1a; 一、核心術語 MCU (Microcontroller Unit) ? 中文&#xff1a;微控制器單元 ? 作用&#xff1a;單片機的核心芯片&#xff0c;集成CPU、存儲器、外設接…

常見框架漏洞之一:Thinkphp5x

ThinkPHP是為了簡化企業級應?開發和敏捷WEB應?開發?誕?的&#xff0c;是?個快速、兼容?且簡單的輕量級國產PHP開發框架&#xff0c;誕?于2006年初&#xff0c;原名FCS&#xff0c;2007年元旦正式更名為 ThinkPHP&#xff0c;遵循Apache2開源協議發布&#xff0c;從Stru…