react數(shù)據(jù)管理中的setState與Props詳解
setState調(diào)用原理
setState
是 React 中用于更新組件狀態(tài)(state)的方法。它的調(diào)用原理可以分為以下幾個(gè)步驟:
- 狀態(tài)的改變:當(dāng)調(diào)用
setState
時(shí),React 會(huì)將新的狀態(tài)對(duì)象與當(dāng)前狀態(tài)對(duì)象進(jìn)行合并(合并過(guò)程是淺合并)。React 不會(huì)直接修改當(dāng)前狀態(tài)對(duì)象,而是創(chuàng)建一個(gè)新的狀態(tài)對(duì)象,以確保不直接修改狀態(tài),從而遵循 React 的不可變性原則。 - 觸發(fā)重新渲染:一旦狀態(tài)更新完成,React 會(huì)調(diào)用組件的
render
方法來(lái)重新渲染組件。在重新渲染過(guò)程中,React 會(huì)生成一個(gè)新的虛擬 DOM 樹(shù)(Virtual DOM)。 - 虛擬 DOM 比較:React 會(huì)將新生成的虛擬 DOM 樹(shù)與之前的虛擬 DOM 樹(shù)進(jìn)行比較,找出兩者之間的差異(所謂的變更集合)。
- 局部更新:React 將變更集合中的差異應(yīng)用到實(shí)際的 DOM 中,以更新用戶界面。這是一個(gè)高效的過(guò)程,因?yàn)?React 僅更新了需要更新的部分,而不是重新渲染整個(gè)頁(yè)面。
- 生命周期方法調(diào)用:在更新完成后,React 會(huì)調(diào)用適當(dāng)?shù)纳芷诜椒?,?
componentDidUpdate
,以便開(kāi)發(fā)者可以執(zhí)行一些操作,例如獲取最新的 DOM 元素引用或執(zhí)行副作用操作。
需要注意的是,由于 setState
是異步的,React 可能會(huì)將多次的 setState
調(diào)用合并成一次更新,以提高性能。這意味著在一個(gè)函數(shù)內(nèi)多次調(diào)用 setState
可能不會(huì)導(dǎo)致多次重新渲染,而是在函數(shù)執(zhí)行結(jié)束后一次性更新?tīng)顟B(tài)和重新渲染。
例如,以下代碼中的多次 setState
調(diào)用會(huì)被合并成一次更新:
this.setState({ count: this.state.count + 1 }); this.setState({ count: this.state.count + 1 });
這個(gè)特性有時(shí)會(huì)導(dǎo)致不直觀的行為,因此可以使用函數(shù)式的 setState
形式來(lái)確保狀態(tài)更新是基于先前的狀態(tài)的,而不受合并的影響:
this.setState((prevState) => ({ count: prevState.count + 1 }));
setState第二個(gè)參數(shù)
this.setState(newState, callback);
newState
是一個(gè)對(duì)象或函數(shù),用于描述要更新的狀態(tài)。這可以是一個(gè)新的狀態(tài)值或一個(gè)函數(shù),該函數(shù)接受前一個(gè)狀態(tài)作為參數(shù),返回新的狀態(tài)。callback
是一個(gè)可選的回調(diào)函數(shù),它會(huì)在狀態(tài)更新完成后被調(diào)用。
例如:
import React, { Component } from 'react'; class Counter extends Component { constructor(props) { super(props); this.state = { count: 0, }; } handleIncrement = () => { this.setState({ count: this.state.count + 1 }, () => { // 回調(diào)函數(shù),會(huì)在狀態(tài)更新后被調(diào)用 console.log('Count updated:', this.state.count); }); } render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.handleIncrement}>Increment</button> </div> ); } }
在上述示例中,當(dāng)點(diǎn)擊按鈕并調(diào)用 handleIncrement
方法時(shí),this.setState
用于增加 count
的值?;卣{(diào)函數(shù)通過(guò) console.log
輸出更新后的 count
值,這是在狀態(tài)更新后被調(diào)用的。
回調(diào)函數(shù)的主要用途包括:
- 執(zhí)行需要在狀態(tài)更新后立即執(zhí)行的代碼。
- 執(zhí)行副作用操作,如發(fā)起網(wǎng)絡(luò)請(qǐng)求或操作 DOM。
- 在狀態(tài)更新后通知其他組件或觸發(fā)其他操作。
props和state區(qū)別
props
(屬性)和 state
(狀態(tài))是 React 中用于管理組件數(shù)據(jù)的兩個(gè)不同概念,它們有以下主要區(qū)別:
來(lái)源:
props
:是由父組件傳遞給子組件的數(shù)據(jù)。父組件通過(guò)屬性(props)將數(shù)據(jù)傳遞給子組件,子組件不可以直接修改這些數(shù)據(jù),它們是只讀的。state
:是組件內(nèi)部維護(hù)的數(shù)據(jù),用于描述組件的特定狀態(tài)。組件可以自己管理和修改自己的狀態(tài)。
可變性:
props
:是不可變的(immutable),子組件不能直接修改從父組件接收的 props。Props 用于從外部傳遞信息給組件,組件應(yīng)該將 props 視為只讀數(shù)據(jù)。state
:是可變的(mutable),組件可以通過(guò)調(diào)用setState
方法來(lái)更新自己的狀態(tài)。
管理:
props
:由父組件管理和傳遞,子組件只能訪問(wèn)和使用 props。state
:由組件自己管理和維護(hù),組件可以在需要時(shí)修改自己的狀態(tài)。
作用:
props
:用于傳遞數(shù)據(jù)給子組件,以控制子組件的行為和顯示。state
:用于管理組件內(nèi)部的狀態(tài),以響應(yīng)用戶交互、數(shù)據(jù)請(qǐng)求、或其他事件。
傳遞:
props
:通過(guò)組件的屬性(props)傳遞給子組件。父組件可以通過(guò)屬性來(lái)控制子組件的行為。state
:在組件內(nèi)部聲明和管理,可以通過(guò)setState
方法來(lái)更新。
默認(rèn)值:
props
:可以為 props 設(shè)置默認(rèn)值,以防止未傳遞某個(gè)屬性時(shí)出現(xiàn)錯(cuò)誤。state
:可以在組件的構(gòu)造函數(shù)中設(shè)置初始狀態(tài)(state)的默認(rèn)值。
更新:
props
:當(dāng)父組件的 props 發(fā)生變化時(shí),會(huì)觸發(fā)子組件的重新渲染,子組件會(huì)接收新的 props。state
:當(dāng)組件的狀態(tài)(state)發(fā)生變化時(shí),會(huì)觸發(fā)組件的重新渲染,從而更新界面。
props改變后如何更新組件
class組件
- 父組件傳遞新的
props
:父組件可以通過(guò)修改傳遞給子組件的props
數(shù)據(jù)來(lái)引發(fā)子組件的更新。這可以通過(guò)在父組件中修改props
值或通過(guò)父組件的狀態(tài)變化來(lái)實(shí)現(xiàn)。 - 子組件的
componentWillReceiveProps
(已廢棄,不推薦使用)、getDerivedStateFromProps
或componentDidUpdate
方法:當(dāng)子組件接收到新的props
后,React 將觸發(fā)這些生命周期方法之一,具體取決于 React 版本和組件實(shí)現(xiàn)。
在 React 16.3 及更早版本中,可以使用 componentWillReceiveProps
生命周期方法來(lái)處理新的 props
。
在 React 16.3 及以后的版本中,推薦使用 getDerivedStateFromProps
靜態(tài)方法或 componentDidUpdate
來(lái)處理新的 props
。
在生命周期方法中更新組件狀態(tài)或執(zhí)行其他操作:在上述生命周期方法中,可以訪問(wèn)新的 props
和組件當(dāng)前的狀態(tài)(this.props
和 this.state
)以及之前的 props
和 state
。可以根據(jù)新的 props
數(shù)據(jù)來(lái)更新組件的狀態(tài),從而觸發(fā)重新渲染。
例如,使用 getDerivedStateFromProps來(lái)處理新的 props:
class MyComponent extends React.Component { static getDerivedStateFromProps(nextProps, prevState) { // 檢查新的 props,并根據(jù)需要更新?tīng)顟B(tài) if (nextProps.someProp !== prevState.someProp) { return { someState: nextProps.someProp, }; } return null; // 不更新?tīng)顟B(tài) } render() { // 渲染組件 return <div>{this.state.someState}</div>; } }
或者componentDidUpdate:
import React, { Component } from 'react'; class MyComponent extends Component { state = { count: 0, }; componentDidUpdate(prevProps, prevState) { if (this.props.someProp !== prevProps.someProp) { console.log('Props changed:', prevProps.someProp, '->', this.props.someProp); } } render() { return <div>{this.props.someProp}</div>; } } export default MyComponent;
React 16.3 及以后的版本,componentWillReceiveProps
生命周期方法已經(jīng)被標(biāo)記為已廢棄,不再推薦使用。相反,推薦使用 getDerivedStateFromProps
或 componentDidUpdate
來(lái)處理 props
的變化。
函數(shù)組件
在函數(shù)組件中,可以使用 React 的鉤子函數(shù)來(lái)判斷組件何時(shí)更新,特別是 useEffect
鉤子。下面是如何在函數(shù)組件中判斷組件何時(shí)更新:
1.使用 useEffect
鉤子:使用useEffect
鉤子可以函數(shù)組件中執(zhí)行副作用操作,并且可以根據(jù)依賴項(xiàng)來(lái)判斷何時(shí)觸發(fā)這些副作用??梢詫?props
或其他狀態(tài)值作為依賴項(xiàng),當(dāng)這些依賴項(xiàng)發(fā)生變化時(shí),useEffect
中的代碼將被執(zhí)行。
import React, { useEffect } from 'react'; function MyComponent(props) { // 使用 useEffect 鉤子來(lái)判斷何時(shí)更新 useEffect(() => { // 這里的代碼在組件每次渲染后都會(huì)執(zhí)行 // 可以在這里根據(jù)新的 props 進(jìn)行操作 console.log('Props updated:', props.someProp); }, [props.someProp]); // 僅在 props.someProp 發(fā)生變化時(shí)執(zhí)行 return <div>{props.someProp}</div>; }
在上面的示例中,我們將 props.someProp
作為 useEffect
的依賴項(xiàng),因此當(dāng) props.someProp
發(fā)生變化時(shí),useEffect
中的代碼將被執(zhí)行,從而可以判斷組件何時(shí)更新。
2.使用 React.memo
(可選):如果希望函數(shù)組件在特定 props
變化時(shí)才進(jìn)行更新,并且不關(guān)心其他的 props
,可以使用 React.memo
來(lái)包裝函數(shù)組件。這將創(chuàng)建一個(gè)經(jīng)過(guò)優(yōu)化的組件,只有在指定的 props
發(fā)生變化時(shí)才會(huì)觸發(fā)重新渲染。
import React from 'react'; function MyComponent(props) { return <div>{props.someProp}</div>; } // 使用 React.memo 包裝組件,只有 someProp 變化時(shí)才重新渲染 export default React.memo(MyComponent);
到此這篇關(guān)于react數(shù)據(jù)管理之setState與Props的文章就介紹到這了,更多相關(guān)react setState與Props內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
useEffect如何通過(guò)form.getFieldValue(‘xxx‘)監(jiān)聽(tīng)Form表單變化
這篇文章主要介紹了useEffect如何通過(guò)form.getFieldValue(‘xxx‘)監(jiān)聽(tīng)Form表單變化問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03react+ts實(shí)現(xiàn)簡(jiǎn)單jira項(xiàng)目的最佳實(shí)踐記錄
這篇文章主要介紹了react+ts實(shí)現(xiàn)簡(jiǎn)單jira項(xiàng)目,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07