React受控組件和非受控組件對(duì)比詳解
引言
在使用React搭建用戶界面時(shí),組件可以分為兩類(lèi):受控組件(Controlled Components)和非受控組件(Uncontrolled Components)。這兩種組件在數(shù)據(jù)處理方式上有著顯著的差異,理解它們的區(qū)別對(duì)于構(gòu)建高效和可控的React應(yīng)用至關(guān)重要。本文將深入探討這兩種組件的定義、特點(diǎn)以及使用場(chǎng)景,并通過(guò)示例代碼幫助你更加清晰地理解它們。
受控組件(Controlled Components)
受控組件是指將表單數(shù)據(jù)的狀態(tài)完全由React組件內(nèi)部的state管理的組件。在受控組件中,表單的值(如 <input>
組件中的內(nèi)容)總是由React的狀態(tài)來(lái)控制。當(dāng)用戶輸入時(shí),React會(huì)通過(guò)事件處理函數(shù)來(lái)更新組件的狀態(tài),從而驅(qū)動(dòng)界面的渲染。
優(yōu)點(diǎn)
- 可預(yù)測(cè)性:因?yàn)榻M件的狀態(tài)總是由React管理,所以數(shù)據(jù)的流動(dòng)清晰明確,便于調(diào)試和維護(hù)。
- 單向數(shù)據(jù)流:在React中,數(shù)據(jù)只從父組件流向子組件,從而保證了組件的數(shù)據(jù)流動(dòng)是單向的,有利于創(chuàng)建可重用的組件。
- 聯(lián)動(dòng)性:多個(gè)表單控件之間的狀態(tài)變化可以很容易地聯(lián)動(dòng),例如在表單中一個(gè)輸入框的值改變可能影響其他輸入框的值。
示例代碼
下面是一個(gè)簡(jiǎn)單的受控組件示例,其中我們創(chuàng)建一個(gè)表單,并讓用戶輸入他們的姓名。
import React, { useState } from 'react'; function ControlledComponent() { const [name, setName] = useState(''); const handleChange = (event) => { setName(event.target.value); }; const handleSubmit = (event) => { event.preventDefault(); alert(`Welcome, ${name}!`); }; return ( <form onSubmit={handleSubmit}> <label> Name: <input type="text" value={name} onChange={handleChange} /> </label> <button type="submit">Submit</button> </form> ); } export default ControlledComponent;
在這個(gè)示例中,我們創(chuàng)建了一個(gè)受控組件 ControlledComponent
。用戶在輸入框中輸入時(shí),handleChange
方法會(huì)被調(diào)用,將輸入值存儲(chǔ)在組件的狀態(tài)中。每次狀態(tài)變化都會(huì)導(dǎo)致組件重新渲染,從而讓輸入框始終顯示最新的值。
非受控組件(Uncontrolled Components)
非受控組件則是更加傳統(tǒng)的表單處理方式。此時(shí),表單數(shù)據(jù)的狀態(tài)并不由React來(lái)管理,而是讓瀏覽器自行處理。我們可以通過(guò)使用 ref
來(lái)直接訪問(wèn)DOM元素及其值,從而在需要時(shí)獲取輸入的數(shù)據(jù)。
優(yōu)點(diǎn)
- 簡(jiǎn)單:對(duì)于一些簡(jiǎn)單的輸入,使用非受控組件可以減少代碼的復(fù)雜性和冗余性。
- 直接操作:直接與DOM交互的方式可能在一些情況下更有效率,特別是在處理大量的動(dòng)態(tài)內(nèi)容時(shí)。
示例代碼
以下是一個(gè)非受控組件的示例:
import React, { createRef } from 'react'; class UncontrolledComponent extends React.Component { constructor(props) { super(props); this.inputRef = createRef(); } handleSubmit = (event) => { event.preventDefault(); alert(`Welcome, ${this.inputRef.current.value}!`); }; render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" ref={this.inputRef} /> </label> <button type="submit">Submit</button> </form> ); } } export default UncontrolledComponent;
在這個(gè)例子中,我們創(chuàng)建了一個(gè)類(lèi)組件 UncontrolledComponent
,并使用 createRef
創(chuàng)建了一個(gè)引用 inputRef
。當(dāng)用戶提交表單時(shí),我們通過(guò) this.inputRef.current.value
獲取輸入框的值,而不是通過(guò)狀態(tài)來(lái)管理。
受控組件與非受控組件的對(duì)比
特點(diǎn) | 受控組件 | 非受控組件 |
---|---|---|
數(shù)據(jù)源 | React的state | DOM的真實(shí)值 |
事件處理 | 依賴于事件處理函數(shù) | 直接通過(guò)refs訪問(wèn) |
界面更新 | 狀態(tài)更新會(huì)重新渲染組件 | 不會(huì)自動(dòng)重新渲染組件 |
適用性 | 適用于需要實(shí)時(shí)反饋和數(shù)據(jù)管理的表單 | 適用于簡(jiǎn)單場(chǎng)景 |
何時(shí)使用受控組件和非受控組件?
選擇使用受控組件還是非受控組件,主要取決于你的需求和場(chǎng)景。
使用受控組件:當(dāng)你需要能夠在用戶輸入時(shí)立即對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證或處理時(shí),一般建議使用受控組件。這種方法提供了更好的數(shù)據(jù)管理體驗(yàn),并且讓你可以輕松實(shí)現(xiàn)復(fù)雜的用戶交互。
使用非受控組件:如果你只需要簡(jiǎn)單的輸入,且不希望為每個(gè)輸入保持狀態(tài),這種情況下使用非受控組件會(huì)讓你的代碼更簡(jiǎn)潔。而且在某些性能敏感的場(chǎng)合,直接與DOM交互的方式也往往具有更高的效率。
結(jié)論
雖然受控組件和非受控組件各有其優(yōu)缺點(diǎn),但在實(shí)際應(yīng)用中,許多開(kāi)發(fā)者更傾向于使用受控組件,因?yàn)樗鼈兡軌蛱峁└玫囊?guī)范性和可維護(hù)性。在構(gòu)建復(fù)雜的用戶輸入交互時(shí),受控組件的實(shí)現(xiàn)大大簡(jiǎn)化了數(shù)據(jù)處理的邏輯和維護(hù)的復(fù)雜性。
希望通過(guò)本文的介紹,你能夠更加清晰地理解React中的受控組件和非受控組件,進(jìn)而在你的項(xiàng)目中做出明智的選擇。記得在選擇組件類(lèi)型時(shí),考慮到項(xiàng)目需求和復(fù)雜程度,以找到最適合的解決方案。
以上就是React受控組件和非受控組件對(duì)比詳解的詳細(xì)內(nèi)容,更多關(guān)于React受控組件和非受控組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
reactjs學(xué)習(xí)解決unknown at rule @tailwind css
這篇文章主要介紹了reactjs學(xué)習(xí)解決unknown at rule @tailwind css問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02React?SSR架構(gòu)Streaming?Render與Selective?Hydration解析
這篇文章主要為大家介紹了React?SSR架構(gòu)Streaming?Render與Selective?Hydration解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03完美解決react-codemirror2?編輯器需點(diǎn)擊一下或者延時(shí)才顯示數(shù)據(jù)的問(wèn)題
這篇文章主要介紹了react-codemirror2編輯器需點(diǎn)擊一下或者延時(shí)才顯示數(shù)據(jù)的問(wèn)題,解決方法也很簡(jiǎn)單,需要手動(dòng)引入自動(dòng)刷新的插件,配置一下參數(shù)就可以了,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08antd中form表單的wrapperCol和labelCol問(wèn)題詳解
最近學(xué)習(xí)中遇到了些問(wèn)題,所以給大家總結(jié),下面這篇文章主要給大家介紹了關(guān)于antd中form表單的wrapperCol和labelCol問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02react-router-dom v6版本實(shí)現(xiàn)Tabs路由緩存切換功能
今天有人問(wèn)我怎么實(shí)現(xiàn)React-Router-dom類(lèi)似標(biāo)簽頁(yè)緩存,很久以前用的是react-router v5那個(gè)比較容易實(shí)現(xiàn),v6變化挺大,但了解react的機(jī)制和react-router的機(jī)制就容易了,本文介紹react-router-dom v6版本實(shí)現(xiàn)Tabs路由緩存切換,感興趣的朋友一起看看吧2023-10-10基于react框架使用的一些細(xì)節(jié)要點(diǎn)的思考
下面小編就為大家?guī)?lái)一篇基于react框架使用的一些細(xì)節(jié)要點(diǎn)的思考。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05ahooks useVirtualList 封裝虛擬滾動(dòng)列表
這篇文章主要為大家介紹了ahooks useVirtualList 封裝虛擬滾動(dòng)列表詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09