2017-03-26 49 views
2

如果您在組件的生命週期中將組件從受控組件轉換爲非受控組件(或相反),則會發出警告。爲什麼不建議將React組件從受控組件切換到非受控組件?

除了這個令人困惑的理由之外,還有其他技術上的原因,這不推薦?

+0

你能分享一個示例代碼來重現此警告嗎?你正在使用哪個版本的ReactJS? –

+0

https://gist.github.com/markerikson/d71cfc81687f11609d2559e8daee10cc基本上所有你需要知道的原因 –

+0

這個要點只描述了爲什麼反應控制了表單輸入。這些信息已經從官方文件中獲得。我正在尋找一種現實的情況,從受控制到非受控制(或vv)的切換會導致錯誤的結果 - 輸入與狀態或競態條件不同步或類似。 – lorefnon

回答

1

根據我的經驗,我認爲最主要的原因是爲了防止混亂意外的行爲(因此 - 錯誤)。

自從ReactJS 15發出這個警告。在以前的主要版本 - 反應14(技術上,反應0.14) - 沒有這樣的警告。

因此,這是一個流行的誤解,說明了可能的混淆。我forked your jsfiddle,並做了以下變化:

  • 切換到ReactJS至14(在技術上,陣營0.14)
  • 我的附加價值兩個value(空字符串)和defaultValue( '你好')。

不再有控制檯警告。這裏有一個誤解:人們可能會認爲默認(初始)值將是'hello',然後 - >因爲輸入被控制 - >所有將來的值更改都將存儲在組件狀態中。

但事實並非如此。默認顯示的值是一個空字符串,不是'hello'。相信我,對於努力掌握控制輸入背後的想法的開發人員來說,這會造成混亂。我親身體驗過它!

因此,切換回反應15,你會得到一個可愛的小警告:

輸入元素不應該不受控制轉向控制(反之亦然)。決定在組件的使用期限內使用受控或不受控制的輸入元素。

它不會告訴你完整的故事爲什麼,但至少它引導你哪裏閱讀並如何來解決它。比沒有警告好多了,對嗎? :-)

0

要直接回答問題:從受控制到不受控制地來回切換不是按預期方式使用該工具,並可能導致一些奇怪的行爲。正如你所提到的那樣,它會讓人很難理解實際發生的事情(作爲程序員,你應該試圖避免這種類型的代碼)。此外,我無法想象需要或期望來回切換的實例。你有什麼樣的例子你需要這個嗎?


這裏有幾件事要注意。如果您從您的評論打開jsfiddle,你會發現兩個警告消息立即彈出:

警告:value道具上input不能爲空。考慮使用 空字符串清除組件或undefined對於 未受控組件。

警告:FormPresenter包含一個輸入值爲 和defaultValue道具的文本類型的輸入。輸入元素必須是受控制的或不受控制的(指定值prop或defaultValue prop,但不能同時爲兩個)。決定使用受控或不受控制的輸入元素並移除其中一個道具。

這裏把JSX供參考:

<input 
    type="text" 
    value={this.state.value} 
    defaultValue={this.state.defaultValue} 
    onChange={this.handleChange} 
    /> 

的第一個警告是告訴你有什麼毛病你傳遞什麼樣的價值,就是它給你,你的錯誤詢問(更多在這一分鐘)。

第二個警告是告訴你,受控組件應該只使用value,而不受控組件應該只使用defaultValue。原因在於,如果您需要爲受控組件設置默認值,則可以將默認值傳遞給value。如果您使用的是不受控制的組件,則只需要設置默認值,因爲您希望瀏覽器正常管理當前值。

所以,現在當你在輸入類型,它爲您提供了第三次警告:

警告:FormPresenter正在改變類型的文本 的不受控制的輸入進行控制。輸入元素不應從未受控制的 切換到受控(反之亦然)。在組件使用期限內使用受控或 未受控輸入元素之間的決定

這與第一個警告有關。由於您違約this.state.valuenull,因此input未被視爲受控制。如果您將默認值更改爲空字符串(''),則您正確控制輸入並且不會收到警告消息。 jsfiddle updated to show this

+0

問題不在於如何解決,而在於可能導致什麼樣的問題。 – lorefnon

+0

啊,我會稍微更新一下 - 我對這些錯誤有所側重。 –

相關問題