天天看點

淺談react受控元件與非受控元件

最近在使用螞蟻金服出品的一條基于react的ant-design UI元件時遇到一個問題,編輯頁面時<code>input</code>輸入框會展示儲存前的資料,但是是用<code>defaultValue</code>就是不起作用,輸入框始終為空值而不是具體的傳入的值。具體編輯頁面中文本框相關的代碼如下:

在給代碼段所屬的元件傳遞<code>value</code> props後,文本框中的預設值一直為空,因為該頁面所在的狀态<code>state</code>中,<code>value</code>所對應的狀态初始值為空,導緻後續異步請求成功後改變value對應的狀态中的值,仍然顯示為空。

google一下具體原因,原來React的<code>form</code>表單元件中的<code>defaultValue</code>一經傳遞值後,後續改變<code>defaultValue</code>都将不起作用,被忽略了。

具體來說這是一種react<code>非受控元件</code>,其狀态是在input的react内部控制,不受調用者控制。可以使用<code>受控元件</code>來實作。

下面就說說這個受控元件與非受控元件,它們都是基于react的form表單元件元素的,具體也可參考react官網這方面介紹

就形式上來說,<code>受控元件</code>就是為某個form表單元件添加<code>value</code>屬性;<code>非受控元件</code>就是沒有添加<code>value</code>屬性的元件;,受控元件的形式如下形式:

添加了<code>value</code> 屬性的表單元件元素其内部是不會維護自己狀态state,元件的value值一旦設定某個具體值就始終是這個值,是以需要調用者來控制元件value的改變。

這種寫法帶來一個問題:渲染後的<code>input</code>元件的使用者互動,使用者輸入的任何值将不起作用,input輸入框中的值始終為<code>Hello!</code>。這與HTML中input表現不一緻。

為此,為了控制該元件,就需要能能夠控制<code>input</code>元件的值,需要借助其内部的狀态state,即元件内部要維護一個狀态<code>state</code>以便配合<code>input</code>元件的<code>onChange</code>和<code>setState</code>方法來完成對元件的控制;例如對上面形式可以進行封裝一個inputItem元件,其内部維護一個<code>state</code>狀态,具體代碼如下:

這樣就可以在外部像下面這樣調用<code>InputItem</code>元件了:

這樣就可以控制react的<code>Input</code>元件了,其實就是需要借助react的<code>有狀态component</code>來完成,因為有狀态component可以内部維護<code>state</code>。

表現形式上,react中沒有添加<code>value</code>屬性的表單元件元素就是非受控元件。表現形式如下:

<code>非受控元件</code>在底層實作時是在其内部維護了自己的狀态state;這樣表現出使用者輸入任何值都能反應到元素上。

在使用react component時,都會遇到受控元件或者非受控元件;在目前,react元件推薦使用<code>stateless component</code>,但是使用該形式來實作react component時使用非受控元件到倒是沒有什麼大問題,若是需要控制受控元素就會有出現問題,表現在:

是以,受控元素就不能使用<code>stateless component</code>來建立。

鑒于受控元件與非受控元件的特點,二者應用的地方也有所不同,主要表現在:

受控元素,一般用在需要動态設定其初始值的情況;例如某些form表單資訊編輯時,input表單元素需要初始顯示伺服器傳回的某個值然後進行編輯。

非受控元素, 一般用于無任何動态初始值資訊的情況; 例如form表單建立資訊時,input表單元素都沒有初始值,需要使用者輸入的情況

繼續閱讀