2015-10-03 53 views
17

當我單擊複選框時,雖然onChange處理程序中的console.log指示狀態更改爲false,但複選標記並不會消失。另一方面,當通過單獨的按鈕改變狀態時,複選標記正確地打開和關閉。反應複選框不會切換

export default class TestComponent extends Component { 

constructor(props) { 
    super(props); 
    this.state = { 
     is_checked: true 
    }; 
    this.updateCheckbox = this.updateCheckbox.bind(this); 
    this.pressButton = this.pressButton.bind(this); 
} 
updateCheckbox(event) { 
    event.preventDefault(); 

    this.setState({is_checked: !this.state.is_checked}); 
    console.log(this.state.is_checked); // This logs 'false' meaning the click did cause the state change 
    console.log(event.target.checked); // However, this logs 'true' because the checkmark is still there 

} 
pressButton(event){ 
    event.preventDefault(); 
    this.setState({is_checked: !this.state.is_checked}); 
} 
render(){ 

    return (
    <input type="checkbox" onChange={this.updateCheckbox} checked={this.state.is_checked} ></input> 
    <button onClick={this.pressButton}>change checkbox state using button</button> 
    ); 
} 
} 
+0

我知道它已經有一段時間,但接受的答案是某種誤導(雖然沒有錯)。此外,我認爲你不應該用雙向綁定來解決這個問題,就像你在自己的答案中一樣。 – ftor

回答

20

我想我明白髮生了什麼。

您單擊該按鈕,並切換is_checked,該選項用於選中或取消選中該框。但最終會觸發一個onChange的複選框,它也會切換狀態......您實際上編碼了一個無限循環。雖然,由於React批量/刪除setState操作,您的代碼不會鎖定您的頁面。

試試這個:

var React = require("react"); 

var Component = React.createClass({ 
    getInitialState: function() { 
     return { 
      isChecked: true 
     }; 
    }, 

    handleCheckboxChange: function(event) { 
     console.log("checkbox changed!", event); 
     this.setState({isChecked: event.target.checked}); 
    }, 

    toggleIsChecked: function() { 
     console.log("toggling isChecked value!"); 
     this.setState({isChecked: !this.state.isChecked}); 
    }, 

    handleButtonClick: function(event) { 
     console.log("button was pressed!", event); 
     this.toggleIsChecked(); 
    }, 

    render: function() { 
     return (
      <div> 
       <input type="checkbox" onChange={this.handleCheckboxChange} checked={this.state.isChecked} /> 
       <button onClick={this.handleButtonClick}>change checkbox state using this button</button> 
      </div> 
     ); 
    } 
}); 

module.exports = Component; 

注意,您可以更清潔的使用作出反應的valueLink使這個代碼(在這裏閱讀更多:https://facebook.github.io/react/docs/two-way-binding-helpers.html

+0

感謝您的幫助。您提供的代碼具有相同的問題,但雙向綁定的鏈接很有幫助。更新我的帖子以顯示工作解決方案。 –

+0

我忘了在'handleCheckboxChange'裏面添加一行,它實際上更新'isChecked'狀態 - 祕密使用'event.target.checked'的值。我更新了代碼,僅供參考。這也是一個小提琴:https://jsfiddle.net/xqb2mxsq/ – sarink

+1

你也可以通過刪除「event.preventDefault();」來解決這個問題。線。因爲這可以防止複選框被檢查。因此它將永遠是相同的狀態。 –

0

改變每做出反應文檔代碼的雙向綁定,以便卡比爾提供了鏈接。

爲了使它工作,我不得不

  1. 使用 「React.createClass」,以使用LinkedStateMixin

    import react from 'react/addons' 
    
    var TestComponent = React.createClass({ 
    mixins: [React.addons.LinkedStateMixin], 
    render: function(){ .... 
    
  2. 刪除的onChange = 'updateCheckbox',而不是 「擴展組件」並改用this.linkState。

    <input type="checkbox" checkedLink={this.linkState(this.state.is_checked)} ></input> 
    
7

這樣做的原因行爲與陣營的實現細節做的 - 更具體的反應如何規格化變化處理。跨瀏覽器的方式。使用無線電和複選框輸入React使用單擊事件來代替更改事件。當您在附加的事件處理程序中應用preventDefault時,會阻止瀏覽器直觀更新收音機/複選框輸入。有兩種可能的解決方法:

  • 使用stopPropagation或者
  • 將撥動到setTimeoutsetTimeout(x => this.setState(x), 0, {is_checked: !this.state.is_checked});

最好不要使用preventDefault可言,除非它是絕對必要的。

看看這個React Github issue欲瞭解更多信息。

+1

擺脫preventDefualt的固定問題對我來說,使用反應15和打字稿2.2(抱歉壞格式化) toggleMyCheckbox(checkboxExent:React.ChangeEvent ){ checkboxExent.preventDefault(); this.setState({ checkboxModel:this.state.checkboxModel, 檢查:this.state.checked }) } 到.. toggleMyCheckbox(checkboxExent:React.ChangeEvent ){ 此。的setState({ checkboxModel:this.state.checkboxModel, 檢查:this.state.checked }) } –

+0

謝謝你,我擺脫了防止違約的也和它爲我工作。 –

0

記住的setState是異步的,因此:

console.log(event.target.checked); 

不得立即反映更改。我的方式來處理多個複選框字段:

toggleCheckbox(name, event) { 
    let obj = {}; 
    obj[name] = !this.state[name]; 
    this.setState(obj); 
} 

字段:

<input type="checkbox" name="active" value={this.state.active} checked={this.state.active} onChange={this.toggleCheckbox.bind(this, 'active')} /> 

<input type="checkbox" name="qtype" value={this.state.qtype} checked={this.state.qtype} onChange={this.toggleCheckbox.bind(this, 'qtype')} />