溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

React源碼中怎么實現(xiàn)受控組件

發(fā)布時間:2021-10-26 10:45:05 來源:億速云 閱讀:151 作者:iii 欄目:web開發(fā)

本篇內容主要講解“React源碼中怎么實現(xiàn)受控組件”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“React源碼中怎么實現(xiàn)受控組件”吧!

在React中一個簡單的受控組件如下:

function App() {   const [num, updateNum] = React.useState(0);      const onChange = ({target: {value}}) => {     updateNum(value);   }    return (     <input value={num} onChange={onChange}/>   ) }

在onChange中會更新num,num作為value prop傳遞給<input/>,達到value受控的目的。

如果讓你來設計,你會怎么做?

我相信大部分同學第一個想法是:將value prop與其他attribute prop一樣處理就行。

我們知道React內部運行有3個階段:

  • schedule 調度更新階段

  • render 進行diff算法的階段

  • commit 進行DOM操作的階段

假設我們要在onChange中觸發(fā)更新改變className,只需要在render階段記錄要改變的className,在commit階段執(zhí)行對應的addClass DOM操作。

同樣的,如果我們要在onChange中觸發(fā)更新改變value,只需要在render階段記錄要改變的value,在commit階段執(zhí)行對應的inputDOM.setAttribute('value', value)操作。

這樣邏輯非常通順。那么事實上呢?

直接改變value的問題
className只是inputDOM上的一個普通屬性。而value則涉及到輸入框光標的位置。

如果我們直接修改value,那么屬性改變后input的光標輸入位置也會丟失,光標會跳到輸入框的最后。

想想我們將1234修改為12534。

1234 --> 12534

需要先將光標位置移動到2之后,再輸入5。

如果setAttribute('value', '12534'),那么光標不會保持在5后面而是跳到4后面。

那么React如何解決這個問題呢?

用非受控的形式實現(xiàn)受控組件

你沒有看錯,React用非受控形式實現(xiàn)了受控組件的邏輯。

簡單的說,不同于className在commit階段受控更新,value則完全是非受控的形式,只在必要的時候受控更新。

因為一旦更新value,那么光標位置就會丟失。

我們稍微修改下Demo,input為受控組件,value始終為1:

function App() {   const num = 1;    return (     <input value={num}/>   ) }

當我們在源碼中打上斷點,輸入2后,實際上會先顯示12,再刪掉2。

只不過這個刪除的過程是同步的所以看起來輸入框內始終只有1。

React源碼中怎么實現(xiàn)受控組件

所以,不同于React其他組件props的更新會經歷schedule - render - commit流程。

對于input、textarea、select,React有一條單獨的更新路徑,這條路徑觸發(fā)的更新被稱為discreteUpdate。

這條路徑的工作流程如下:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)

  2. 先以非受控的形式更新表單DOM

  3. 以同步的優(yōu)先級開啟一次更新

  4. 更新后的value在commit階段并不會像其他props一樣作用于DOM

  5. 調用restoreStateOfTarget方法,比較DOM的實際value(即步驟1中的非受控value)與步驟3中更新的value,如果相同則退出,如果不同則用步驟3的value更新DOM

什么情況下這2個value會相同呢?

我們正常的受控組件就是相同的情況:

function App() {   const [num, updateNum] = React.useState(0);      const onChange = ({target: {value}}) => {     updateNum(value);   }    return (     <input value={num} onChange={onChange}/>   ) }

什么情況下這2個value會不同呢?

上面的Demo中,雖然受控,但是沒有調用updateNum更新value的情況:

function App() {   const num = 1;    return (     <input value={num}/>   ) }

在這種情況下,步驟1的非受控value變?yōu)榱?2,步驟3的受控value還是1,所以最終會用1再更新下DOM的value。

到此,相信大家對“React源碼中怎么實現(xiàn)受控組件”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI