2015-10-03 52 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')} />