react复选框不会切换

IT技术 checkbox reactjs
2021-04-29 12:58:37

当我单击复选框时,尽管 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>
    );
}
}
4个回答

我想我明白发生了什么。

您单击该按钮,它会切换is_checked,选中或取消选中该框。但这最终会触发onChange复选框的 ,这也会切换状态......您实际上已经编写了一个无限循环。虽然,由于 React 批处理/去抖动setState操作,您的代码不会锁定您的页面。

试试这个:

2019 年钩子 API 更新:

import React, { useState } from 'react';

const Component = () => {
  const [isChecked, setIsChecked] = useState(true);

  return (
    <div>
      <input
        type="checkbox"
        onChange={(event) => setIsChecked(event.currentTarget.checked)}
        checked={isChecked}
      />
      <button onClick={() => setIsChecked(!isChecked)}>
        change checkbox state using this button
      </button>
    </div>
  );
};

原来的:

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;

请注意,您可以使用 React 的 valueLink 使此代码更简洁(在此处阅读更多信息:https ://facebook.github.io/react/docs/two-way-binding-helpers.html

这种行为的原因与 React 的实现细节有关 - 更具体地说是 React 如何规范化跨浏览器的更改处理。对于单选和复选框输入,React 使用单击事件代替更改事件。当您preventDefault在附加的事件处理程序中应用时,这会阻止浏览器从视觉上更新单选框/复选框输入。有两种可能的解决方法:

  • stopPropagation交替使用
  • 将开关放入setTimeoutsetTimeout(x => this.setState(x), 0, {is_checked: !this.state.is_checked});

preventDefault除非绝对必要,否则最好不要使用

查看这个React Github 问题以获取更多信息。

请记住 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')} />

根据 Kabir 提供链接的双向绑定的 React 文档更改了代码。

为了使它工作,我必须

  1. 使用“React.createClass”而不是“extends Component”来使用 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>