2016-08-24 51 views
9

我對React和複選框有一個非常惱人的問題。我正在使用的應用程序需要一個複選框列表,這些複選框表示在後端保留的設置。 有一個選項可將設置恢復到原始狀態在React中設置複選框「檢查」屬性

首先,我創建了一個組件,其中包含一個像設置圖一樣的對象。每個設置都有一個鍵和一個布爾值。因此:

{ 
    bubbles: true, 
    gregory: false 
} 

是爲表示:

<input type="checkbox" value="bubbles" checked="checked" /> 
<input type="checkbox" value="gregory" /> 

現在看來陣營是無知一個複選框應該是怎樣工作的。我不想設置複選框的值,我想要「checked」屬性。

但是,如果我嘗試這樣的事:

<input 
    type="checkbox" 
    value={setting} 
    checked={this.settings[setting]} 
    onChange={this.onChangeAction.bind(this)} 
/> 

我得到這樣的警告:

警告:AwesomeComponent正在改變類型複選框的不受控制的輸入進行控制。輸入元素不應從非受控狀態切換爲受控狀態(反之亦然)。決定在組件的使用期限內使用受控或不受控制的輸入元素。更多信息:一些無用的文檔頁面我看了幾次無果]

所以我決定創建另一個組件包裹每一個人複選框,我得到這個:

<input 
    type="checkbox" 
    checked={this.state.checked} 
    onChange={this.onChangeAction.bind(this)} 
/> 

現在checked是直接在我的州存在的財產。

這就產生了同樣的警告,所以我嘗試使用defaultChecked

<input 
    type="checkbox" 
    defaultChecked={this.state.checked} 
    onChange={this.onChangeAction.bind(this)} 
/> 

這使得警告消失,但現在是無法將checked值重置爲默認的。所以我試着玩componentWillReceiveProps這個方法,這樣我很確定我的狀態是正確的,this.state.checked是正確的,組件再次呈現。

它的確如此。但是複選框仍然保持原樣。 現在我留下了那個醜陋的警告,我正在使用checked。 我該如何解決這個問題,讓警告消失?

我在想,也許有辦法強制重新渲染組件,所以它會捕獲新的值並使用它。但我不知道該怎麼做。也許這個組件禁止警告只有?那可能嗎?也許還有別的可以做的事情?

回答

28

如果您將複選框的checked屬性設置爲null或,則會出現問題。

這些是JS中的「錯誤」值,但是完全是React treats a value of null as if the property was not set。由於複選框的默認狀態是未選中狀態,所以一切都會正常工作。如果您隨後將checked設置爲true React認爲該屬性突然出現!這是React數字從非控制切換到控制的時候,因爲現在支持checked存在。

在您的示例中,您可以通過將checked={this.settings[setting]}更改爲checked={!!this.settings[setting]}來擺脫此警告。注意雙重爆炸(!!)。他們會將nullundefined轉換爲false(並且只保留true),因此React將註冊您的checked屬性,其值爲false,並以受控表單組件開始。

我也有這個問題,我也讀了docs about controlled-components幾次無濟於事,但我終於明白了,所以我想我會分享。此外,由於version 15.2.0正常輸入觸發由設置value控制,而複選框被初始化爲由設置checked控制,無論其value財產,這增加了一點混亂。

+2

在浪費了,因爲我想我明白這個問題一個小時,由於從反應的非常具體的警告信息:只需用價值falsechecked託您的CheckBox組件的添加defaultProps屬性。不。這是後來定義的未定義變量。謝謝。 – Don

+2

我無法大拇指這個答案。我有條件地添加和刪除'checked'屬性本身,這在簡單的HTML日子裏是很好的做法。我花了20分鐘疑惑爲什麼這個錯誤消息正在發生。 ReactJS錯誤消息確實應該有一個特殊情況,承認不一致的古怪,即HTML複選框輸入,以便其他人不會遇到這種情況。 –

+1

令人難以置信的答案:)這是一個很好的技巧,我不知道(使用雙重轟擊立即轉換爲布爾值) –

1

基本上,defaultChecked意味着你不想控制輸入 - 它只是呈現這個值,然後就沒有辦法控制它。此外,value不應該使用,但checked而不是,所以你的第二個代碼應該是正確的。而且你不應該同時使用它們。

<input 
    type="checkbox" 
    checked={this.state.checked} 
    onChange={this.onChangeAction.bind(this)} 
/> 

你能用這種行爲創建一個小提琴嗎?

0

您可以將您的數據的狀態,然後利用與個別複選框相關的checked屬性的設置狀態

{ this.state.data.map(function(item, index) { 
     return (

     <input type="checkbox" checked={item.value} onChange={this.handleChange.bind(this, index)}/> 

    ); 
    }.bind(this)) 
    } 

樣本數據中的狀態是

data: [{name:'bubbles', value: true}, {name:'gregory', value: false}] 

JSFIDDLE

4

Amoebe的回答是正確的,但我認爲比雙銀行有更清潔的解決方案(!!)。

import React from 'react'; 

const Checkbox = ({checked}) => (
    <div> 
     <input type="checkbox" checked={checked} /> 
    </div> 
); 

Checkbox.defaultProps = { 
    checked: false 
}; 

export default Checkbox; 
相關問題