React Checkbox 未发送 onChange

问题描述 投票:0回答:9

TLDR:使用defaultChecked而不是checked,工作jsbin

尝试设置一个简单的复选框,在选中时会划掉其标签文本。由于某种原因,当我使用该组件时,handleChange 没有被触发。谁能解释我做错了什么?

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    console.log('handleChange', this.refs.complete.checked); // Never gets logged
    this.setState({
      complete: this.refs.complete.checked
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            checked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});

用途:

React.renderComponent(CrossoutCheckbox({text: "Text Text", complete: false}), mountNode);

解决方案:

使用checked不会让底层值改变(显然),因此不会调用onChange处理程序。切换到defaultChecked似乎可以解决这个问题:

var CrossoutCheckbox = React.createClass({
  getInitialState: function () {
    return {
        complete: (!!this.props.complete) || false
      };
  },
  handleChange: function(){
    this.setState({
      complete: !this.state.complete
    });
  },
  render: function(){
    var labelStyle={
      'text-decoration': this.state.complete?'line-through':''
    };
    return (
      <span>
        <label style={labelStyle}>
          <input
            type="checkbox"
            defaultChecked={this.state.complete}
            ref="complete"
            onChange={this.handleChange}
          />
          {this.props.text}
        </label>
      </span>
    );
  }
});
checkbox onchange reactjs
9个回答
300
投票

要获取复选框的选中状态,路径为:

this.refs.complete.state.checked

另一种方法是从传递到

handleChange
方法的事件中获取它:

event.target.checked

53
投票

在这种情况下最好不要使用 refs。用途:

<input
    type="checkbox"
    checked={this.state.active}
    onClick={this.handleClick}
/>

有一些选项:

checked
vs
defaultChecked

前者会响应状态变化点击。 后者会忽略状态变化。

onClick
vs
onChange

前者总是在点击时触发。 如果

checked
元素上存在
input
属性,则后者不会在点击时触发。


25
投票

如果您有一个如下所示的

handleChange
函数:

handleChange = (e) => {
  this.setState({
    [e.target.name]: e.target.value,
  });
}

您可以创建自定义

onChange
函数,使其行为类似于文本输入:

<input
  type="checkbox"
  name="check"
  checked={this.state.check}
  onChange={(e) => {
    this.handleChange({
      target: {
        name: e.target.name,
        value: e.target.checked,
      },
    });
  }}
/>

15
投票

如果您不想在输入 DOM 上使用 onChange 处理程序,则可以使用

onClick
属性作为替代方案。
defaultChecked
,该条件可能会为 v16 IINM 留下固定状态。

 class CrossOutCheckbox extends Component {
      constructor(init){
          super(init);
          this.handleChange = this.handleChange.bind(this);
      }
      handleChange({target}){
          if (target.checked){
             target.removeAttribute('checked');
             target.parentNode.style.textDecoration = "";
          } else {
             target.setAttribute('checked', true);
             target.parentNode.style.textDecoration = "line-through";
          }
      }
      render(){
         return (
            <span>
              <label style={{textDecoration: this.props.complete?"line-through":""}}>
                 <input type="checkbox"
                        onClick={this.handleChange}
                        defaultChecked={this.props.complete}
                  />
              </label>
                {this.props.text}
            </span>
        )
    }
 }

我希望这对将来的人有帮助。


13
投票

如果有人正在寻找通用事件处理程序,可以或多或少地使用以下代码(假设为每个输入设置了 name 属性):

    this.handleInputChange = (e) => {
        item[e.target.name] = e.target.type === "checkbox" ? e.target.checked : e.target.value;
    }

3
投票

使用defaultChecked时,onChange不会在移动设备上调用handleChange。作为替代方案,您可以使用 onClick 和 onTouchEnd。

<input onClick={this.handleChange} onTouchEnd={this.handleChange} type="checkbox" defaultChecked={!!this.state.complete} />;

1
投票

在 Material ui 中,复选框的状态可以获取为

this.refs.complete.state.switched

0
投票

对于以后遇到这个问题的人。我的问题是在标签的

name
中引用输入
id
而不是
htmlFor

所以改变这个:

<input type="checkbox" name="test" value="isGood" onChange={() => console.log('called')} />
<label htmlFor="test" >Is Good?</label>

到此

<input type="checkbox" name="test" id="test" value="isGood" onChange={() => console.log('called')} />
<label htmlFor="test" >goood</label>

解决了问题


0
投票

这里是 React 18 文档:https://react.dev/reference/react-dom/components/input#my-checkbox-doesnt-update-when-i-click-on-it

// ✅ Good: controlled checkbox with onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
// 🔴 Bug: controlled checkbox with no onChange handler
<input type="checkbox" checked={something} />
// ✅ Good: uncontrolled checkbox with an initial value
<input type="checkbox" defaultChecked={something} />
© www.soinside.com 2019 - 2024. All rights reserved.