簡體   English   中英

為什么不建議將 React 組件從受控切換為不受控?

[英]Why is it not recommended to switch a React component from controlled to uncontrolled?

如果您在組件的生命周期內將組件從受控狀態轉換為不受控狀態(反之亦然),React 會發出警告。

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

直接回答問題:從受控到不受控來回切換不是按預期使用工具,可能會導致一些奇怪的行為。 正如您所提到的,這會使您很難理解實際發生的事情(作為程序員,您應該盡量避免這種類型的代碼)。 此外,我想不出需要或需要來回切換的實例。 你有什么地方需要這個的例子嗎?


這里有幾點需要注意。 如果您從評論中打開jsfiddle ,您會注意到兩條警告消息立即彈出:

Warning: value prop on input should not be null.考慮使用空字符串來清除組件或undefined的組件。

警告:FormPresenter 包含帶有 value 和 defaultValue 屬性的文本類型的輸入。 輸入元素必須是受控或不受控(指定 value prop 或 defaultValue prop,但不能同時指定兩者)。 在使用受控或不受控輸入元素之間做出決定,並刪除其中一個道具。

將 jsx 放在這里以供參考:

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

第一個警告是告訴您作為值傳遞的內容有問題,這就是為什么它會給出您所詢問的錯誤(稍后會詳細介紹)。

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

所以,現在當你輸入時,它會給你第三個警告:

警告:FormPresenter 正在將不受控制的文本類型輸入更改為受控制。 輸入元素不應從不受控制切換到受控(反之亦然)。 在組件的生命周期內決定使用受控或非受控輸入元素

這與第一個警告有關。 因為您將this.state.value默認為null ,所以input不受控制。 如果您將默認值更改為空字符串 ( '' ),您將正確控制輸入並且不會收到警告消息。 jsfiddle 已更新以顯示此內容

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

此警告自 ReactJS 15 以來出現。在以前的主要版本 - React 14(技術上,React 0.14)中 - 沒有這樣的警告。

因此,這里有一個流行的誤解,它說明了一種可能的混淆。 分叉了你的 jsfiddle並做了以下更改:

  • 切換到 ReactJS 到 14(技術上,React 0.14)
  • 我為value (空字符串)和defaultValue ('hello')添加了值。

不再有控制台警告。 這是一種誤解:人們可能認為默認(初始)值將是“hello”,然后 -> 因為輸入是受控制的 -> 所有未來的值更改都將存儲在組件 state 中。

但事實並非如此 默認顯示值是一個空字符串,而不是“你好”。 相信我,對於難以理解受控輸入背后的想法的開發人員來說,這會造成混淆。 我親身經歷過!

因此,切換回 React 15,你會得到一個很好的小警告:

輸入元素不應從不受控制切換到受控(反之亦然)。 在組件的生命周期內決定使用受控或非受控輸入元素。

它並沒有告訴你完整的故事為什么,但至少它指導你在哪里閱讀以及如何解決它。 總比沒有警告好得多,對吧? :-)

您可能一直在使用具有兩個屬性“value={variable1}”和“defaultValue={something}”的輸入字段。 像這樣 -->

<input 
value={mobile}
onChange={(e) => setMobile(e.target.value)} 
type="text"
defaultValue="XXXXXXXXXX"
/>

只需刪除 defaultValue 屬性。 像這樣 -->

<input 
value={mobile}
onChange={(e) => setMobile(e.target.value)} 
type="text"
/>

就是這樣。 快樂編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM