【React】React18 Hooks 之 useReducer

目錄

  • useReducer
    • 案例1:useReducer不帶初始化函數
    • 案例2:useReducer帶初始化函數
    • 注意事項1:dispatch函數不會改變正在運行的代碼的狀態
    • 注意事項2:獲取dispatch函數觸發后 JavaScript 變量的值
    • 注意事項3:觸發了reducer,但頁面沒有更新

在這里插入圖片描述

React官方文檔

useReducer

useReducer是一個 React Hook,可讓你向組件添加一個Reducer 。
用法:

const [state, dispatch] = useReducer(reducer, initialArg, init?)
  • reducer:指定狀態如何更新的 Reducer 函數,接受兩個參數state(狀態)和action(操作)兩個參數,并返回下一個狀態
  • initialArg:初始值,可以是任何類型的值
  • 可選 init:應返回初始狀態的初始化函數。如果未指定,則將初始狀態設置為initialArg。否則,將初始狀態設置為調用的結果init(initialArg)

useReducer返回一個包含兩個值的數組:

  • state(當前狀態):在第一次渲染期間,它被設置為init(initialArg)或initialArg(如果沒有init)
  • dispatch:該dispatch函數可讓您將狀態更新為不同的值并觸發重新渲染

案例1:useReducer不帶初始化函數

步驟:
1、定義一個reducer函數,根據不同的action返回不同的狀態
2、組件中調用userReducer(reducer,initialArg)
3、調用dispatch({type:“INC”})通知reducer產生一個新的狀態,隨后更新UI


const idata = {count:0};
function reducer(state, action) {console.log(state,"state")console.log(action,"action")switch (action.type) {case "INC":return {count:state.count+1}case "DEC":return {count:state.count-1}case "SET":return {count:action.payload}default:return {count:idata}}
}
function App() {const [state, dispatch] = useReducer(reducer, idata);return (<div className="App">this is App{state.count}<button onClick={() => dispatch({ type: "INC" })}>+</button><button onClick={() => dispatch({ type: "DEC" })}>-</button><button onClick={() => dispatch({ type: "SET", payload: 100 })}>update</button></div>);
}export default App;

案例2:useReducer帶初始化函數

設置initData為初始化函數,設置state初始狀態

#App.js
import Son from "./Son.js";
function App() {return (<div className="App"><Son idata={{count:1}}></Son></div>);}export default App;
#Son.js
import { useReducer } from "react";const initData=()=>{return {count:0}
}function reducer(state, action) {console.log(state,"state")console.log(action,"action")switch (action.type) {case "INC":return {count:state.count+1}case "DEC":return {count:state.count-1}case "SET":return {count:action.payload}default:return initData() }
}const  Son = ({idata})=> {console.log(idata,"idata")const [state, dispatch] = useReducer(reducer, idata,initData);return (<div className="App">this is App<div>Count: {state.count}</div><button onClick={() => dispatch({ type: "INC" })}>+</button><button onClick={() => dispatch({ type: "default" })}>default</button><button onClick={() => dispatch({ type: "DEC" })}>-</button><button onClick={() => dispatch({ type: "SET", payload: 100 })}>update</button></div>);
}export default Son;

注意事項1:dispatch函數不會改變正在運行的代碼的狀態

點擊update按鈕,handler函數觸發之后,頁面Count顯示為100,但是打印出來state.count為0

dispatch函數不會改變正在運行的代碼的狀態,更新狀態會請求使用新狀態值進行另一次渲染,但不會影響state已在運行的事件處理程序中的 JavaScript 變量。

#Son.js
import { useReducer } from "react";
const initData = () => {return { count: 0 }
}
function reducer(state, action) {switch (action.type) {case "INC":return { count: state.count + 1 }case "DEC":return { count: state.count - 1 }case "SET":return { count: action.payload }default:return initData()}
}const Son = ({ idata }) => {
const [state, dispatch] = useReducer(reducer, idata, initData);const handler =()=>{dispatch({ type: "SET", payload: 100 })console.log(state.count,"state")setTimeout(()=>{console.log(state.count,"state")},1000)}return (<div className="App">this is App<div>Count: {state.count}</div><button onClick={() => dispatch({ type: "INC" })}>+</button><button onClick={() =>  dispatch({ type: "default" })}>default</button><button onClick={() => dispatch({ type: "DEC" })}>-</button><button onClick={() => handler()}>update</button></div >);
}export default Son;

注意事項2:獲取dispatch函數觸發后 JavaScript 變量的值

執行reducer(state, action)之后,就可以拿到最新的變量的值

  const handler =()=>{let action = { type: "SET", payload: 100 };dispatch(action)console.log(state,"state") //打印0setTimeout(()=>{console.log(state,"state")  //打印0},1000)const nextState = reducer(state, action);console.log(nextState,'nextState')  //打印100}

注意事項3:觸發了reducer,但頁面沒有更新

直接更改狀態中的對象或數組,并不會重新渲染。因為下一個狀態等于前一個狀態,則React 將忽略您的更新Object.is,指向的還是同一個引用地址。所以需要始終更新狀態中的對象和狀態中的數組。如下:

function reducer(state, action) {switch (action.type) {case 'incremented_age': {// ? Correct: creating a new objectreturn {...state,age: state.age + 1};}case 'changed_name': {// ? Correct: creating a new objectreturn {...state,name: action.nextName};}// ...}
}

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

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

相關文章

webrtc sfu性能壓測

1. 前言 不少網友最近私信我&#xff0c;咨詢webrtc sfu服務端性能問題&#xff0c;SRS開源服務能支持多少路webrtc流&#xff0c;mediasoup單房間能支持多少個人&#xff0c;推流能接入多少路&#xff0c;拉流能拉取多少路&#xff1f;720p能支持多少路&#xff0c;360p能支持…

Spring Boot集成olingo快速入門demo

1.什么是olingo&#xff1f; Apache Olingo 是個 Java 庫&#xff0c;用來實現 Open Data Protocol (OData)。 Apache Olingo 包括服務客戶端和 OData 服務器方面。 Open Data Protocol &#xff08;開放數據協議&#xff0c;OData&#xff09; 是用來查詢和更新數據的一種W…

【吊打面試官系列-MyBatis面試題】MyBatis 實現一對多有幾種方式,怎么操作的?

大家好&#xff0c;我是鋒哥。今天分享關于 【MyBatis 實現一對多有幾種方式,怎么操作的&#xff1f;】面試題&#xff0c;希望對大家有幫助&#xff1b; MyBatis 實現一對多有幾種方式,怎么操作的&#xff1f; 有聯合查詢和嵌套查詢。聯合查詢是幾個表聯合查詢,只查詢一次,通過…

觀察矩陣(View Matrix)、投影矩陣(Projection Matrix)、視口矩陣(Window Matrix)及VPM矩陣及它們之間的關系

V表示攝像機的觀察矩陣&#xff08;View Matrix&#xff09;&#xff0c;它的作用是把對象從世界坐標系變換到攝像機坐標系。因此&#xff0c;對于世界坐標系下的坐標值worldCoord(x0, y0, z0)&#xff0c;如果希望使用觀察矩陣VM將其變換為攝像機坐標系下的坐標值localCoord(x…

【滲透入門】HTTP請求包

文章目錄 前言HTTP GET請求包HTTP POST請求包Content-Type 前言 HTTP&#xff08;HyperText Transfer Protocol&#xff09;請求包&#xff0c;是Web通信的基礎。HTTP請求包格式主要由以下幾部分組成&#xff1a; 請求行&#xff1a;包含了請求方法&#xff08;GET、POST、PUT…

32單片機,C語言與匯編聯合編譯的幾種方式

適用編譯器&#xff1a;Keil5 方式一&#xff1a; 單獨創建一個.s匯編文件&#xff0c;在匯編文件內對函數進行EXPORT聲明 r0寄存器是函數傳入的第一個參數&#xff0c;r1寄存器是函數傳入的第二個參數&#xff0c;以次類推。參數最多不確定是到r4為止&#xff0c;還是到r12…

Node.js-path 模塊

path 模塊 path 模塊提供了 操作路徑 的功能&#xff0c;如下是幾個較為常用的幾個 API&#xff1a; 代碼實例&#xff1a; const path require(path);//獲取路徑分隔符 console.log(path.sep);//拼接絕對路徑 console.log(path.resolve(__dirname, test));//解析路徑 let pa…

Robust Regression

最小二乘回歸受數據中的離群點的影響較大&#xff0c;穩健回歸通過降低離群點的影響緩解此問題。M估計法是穩健回歸的重要方法之一&#xff0c;M 估計法的目標函數為&#xff1a; m i n ∑ ρ ( ? i ) m i n ∑ ρ ( y i ? β ^ ? X i ) min\sum\rho(\epsilon_i) min\sum\…

vulhub-activemq(CVE-2016-3088)

在 Apache ActiveMQ 5.12.x~5.13.x 版本中&#xff0c;默認關閉了 fileserver 這個應用&#xff08;不過&#xff0c;可以在conf/jetty.xml 中開啟&#xff09;&#xff1b;在 5.14.0 版本后&#xff0c;徹底刪除了 fileserver 應用。【所以在滲透測試過程中要確定好 ActiveMQ …

word 使用手冊

word 文檔中如何將下行的指定文字退格到上行中 就像是這樣的 編號&#xff1a;111 密碼&#xff1a;222 編號&#xff1a;123 密碼&#xff1a;321 編號&#xff1a;124 密碼&#xff1a;331 變成 編號&#xff1a;111密碼&#xff1a;222 編號&#xff1a;123密碼&#xff1…

數據結構1:C++實現變長數組

數組作為線性表的一種&#xff0c;具有內存連續這一特點&#xff0c;可以通過下標訪問元素&#xff0c;并且下標訪問的時間復雜的是O(1)&#xff0c;在數組的末尾插入和刪除元素的時間復雜度同樣是O(1)&#xff0c;我們使用C實現一個簡單的邊長數組。 數據結構定義 class Arr…

華為OD機試 - 來自異國的客人(Java 2024 D卷 100分)

華為OD機試 2024D卷題庫瘋狂收錄中&#xff0c;刷題點這里 專欄導讀 本專欄收錄于《華為OD機試&#xff08;JAVA&#xff09;真題&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一題都有詳細的答題思路、詳細的代碼注釋、樣例測…

新手教學系列——前后端分離API優化版

在之前的文章《Vue 前后端分離開發:懶人必備的API SDK》中,我介紹了通過Object對象自動生成API的方法。然而,之前的代碼存在一些冗余之處。今天,我將分享一個改進版本,幫助你更高效地管理API。 改進版API SDK 首先,讓我們來看一下改進后的代碼: import request from …

深入理解 KVO

在 iOS 中&#xff0c;KVO&#xff08;Key-Value Observing&#xff09;是一個強大的觀察機制&#xff0c;它的底層實現相對復雜。KVO 利用 Objective-C 的動態特性&#xff0c;為對象的屬性提供觀察能力。 KVO 的底層實現 1. 動態子類化 當一個對象的屬性被添加觀察者時&am…

6、Redis系統-數據結構-01-String

Redis 數據結構簡介 前言 Redis 是一個高性能的內存數據庫&#xff0c;其關鍵在于其數據結構的設計。Redis 數據結構是指底層實現 Redis 鍵值對中值的數據類型的方式。它包括了以下幾種主要對象&#xff1a; String&#xff08;字符串&#xff09;對象&#xff1a;最基本的數…

[C++][CMake][流程控制]詳細講解

目錄 1.條件判斷1.基本表達式2.邏輯判斷3.比較4.文件操作5.其他 2.循環1.foreach2.while 1.條件判斷 在進行條件判斷的時候&#xff0c;如果有多個條件&#xff0c;那么可以寫多個elseif&#xff0c;最后一個條件可以使用else&#xff0c;但是開始和結束是必須要成對出現的&am…

WordPress常見問題及簡要說明

1. 如何安裝WordPress? 簡要說明&#xff1a;WordPress是一個流行的內容管理系統&#xff0c;可以幫助用戶快速搭建網站。安裝WordPress需要以下幾個步驟&#xff1a;下載WordPress安裝包、上傳到服務器、創建數據庫、配置數據庫信息、完成安裝。 2. 如何創建一個新的WordPr…

掌握電量脈搏:WebKit 電池狀態(Battery Status API)支持全解析

掌握電量脈搏&#xff1a;WebKit 電池狀態&#xff08;Battery Status API&#xff09;支持全解析 隨著移動設備的廣泛使用&#xff0c;Web 應用對設備的電池狀態信息的需求日益增長。Battery Status API 提供了一種方式&#xff0c;允許 Web 應用訪問設備的電池信息&#xff…

【反悔貪心 反悔堆】1642. 可以到達的最遠建筑

本文涉及知識點 反悔貪心 反悔堆 LeetCode1642. 可以到達的最遠建筑 給你一個整數數組 heights &#xff0c;表示建筑物的高度。另有一些磚塊 bricks 和梯子 ladders 。 你從建筑物 0 開始旅程&#xff0c;不斷向后面的建筑物移動&#xff0c;期間可能會用到磚塊或梯子。 當…

Spring Boot中的全局異常處理

Spring Boot中的全局異常處理 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01;今天我們將探討如何在Spring Boot應用中實現全局異常處理&#xff0c;這是保證應用…