Javascript React复选框未将其状态设置为单击标签时选中

Javascript React复选框未将其状态设置为单击标签时选中,javascript,reactjs,Javascript,Reactjs,我有一个问题,我的自定义复选框不起作用, 我不太熟悉React,也找不到更好的地方来学习它。你能检查我的代码并告诉我我做错了什么吗 import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; class Checkbox extends React.Component { constructor(props) { super(prop

我有一个问题,我的自定义复选框不起作用, 我不太熟悉React,也找不到更好的地方来学习它。你能检查我的代码并告诉我我做错了什么吗

    import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

class Checkbox extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      checked: false
    };
    this.handleChange = this.handleChange.bind(this);
    this.checkbox = React.createRef();
    this.handleClick = () => {
      this.checkbox.current.click();
    };
  }

  componentDidMount() {
    this.setState({'checked' : this.props.checked});
  }

  handleChange() {
    this.setState({'checked' : !this.state.checked});
  }

  render() {
    let {
      className,
      label,
      ...attributes
    } = this.props;

    const classes = classNames(
      'checkbox',
      className,
    );

    return (
      <div className={classes}>
        <input id="checkbox_1" type="checkbox" checked={this.state.checked} onChange={this.handleChange} {...attributes} ref={this.checkbox} />
        <label for="checkbox_1" className="checkbox-label" onClick={this.handleClick}>{label}</label>
      </div>
    );
  }
}

Checkbox.defaultProps = {
  checked: false,
  className: '',
  label: null
};

Checkbox.propTypes = {
  checked: PropTypes.bool,
  className: PropTypes.string,
  onClick: PropTypes.func,
  label: PropTypes.string
};

export default Checkbox;
从“React”导入React;
从“道具类型”导入道具类型;
从“类名称”导入类名称;
类复选框扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
勾选:假
};
this.handleChange=this.handleChange.bind(this);
this.checkbox=React.createRef();
this.handleClick=()=>{
this.checkbox.current.click();
};
}
componentDidMount(){
this.setState({'checked':this.props.checked});
}
handleChange(){
this.setState({'checked':!this.state.checked});
}
render(){
让{
类名,
标签,
…属性
}=这是道具;
常量类=类名(
“复选框”,
类名,
);
返回(
{label}
);
}
}
Checkbox.defaultProps={
勾选:假,
类名:“”,
标签:空
};
Checkbox.propTypes={
选中:PropTypes.bool,
类名:PropTypes.string,
onClick:PropTypes.func,
标签:PropTypes.string
};
导出默认复选框;
问题是这个组件没有被检查,但如果我将state设置为true,它不会取消选中,如果我将控制台日志安装到handleChange或handleClick,我会在单击时得到console.logged,但仅在第一次单击时,我不确定这是什么意思。在这里的另一篇文章中,我指出,可能是单击时我选中并取消选中的问题,因此我创建了一个无限循环,但在这种情况下,我认为应该有一个console.log的无限循环。 如果我的代码是完全错误的,请随意编辑它,因为你希望,但如果它不是一个很大的忙,请尝试为我评论更改的部分,以便我更好地了解发生了什么:D

提前感谢。

欢迎来到stackoverflow:)

我认为你的问题在于

handleChange() {
  this.setState({'checked' : this.state.checked});
}
您没有更改状态,只是想用相同的值再次设置它。当您将其更改为:

handleChange() {
  this.setState({'checked' : !this.state.checked});
}
编辑:

因此,输入没有从选中变为未选中的真正问题是将
{…attributes}
交给输入。这似乎链接到“checked”属性,该属性会干扰输入元素的默认选中值


此外,在使用react时,您应该使用
htmlFor
属性,而不是
for

这也是一个HTML问题,您必须将标签与输入链接起来,以便它们一起触发,请参阅下面的解决方案,这也可能有帮助()

复选框演示
我不激活复选框

我激活复选框
我还激活了复选框
问题之一是,您在
defaultProps
中设置了一个默认属性
checked:false
,并且该属性总是通过
{…attributes}
输入上设置的,因此您总是有效地将该值写入false,这就是为什么状态更改不会产生任何差异

要修复此问题,您可以取消该默认属性(也可以取消在
componentDidMount
中设置状态),或者在默认情况下停止将所有
属性
数据抛出到
输入
元素中。由你决定

现在,您应该能够看到复选框get checked/unchecked

至于在
label
元素上将
的属性
更改为
htmlFor
,实际上这将基本上将
label
元素绑定到
input
,因此您不必为
label
实现
onClick
处理程序。因此,一旦修复了此属性,只需在
标签
上完全取消您的
onClick
。以下是最终代码:

总而言之,以下是需要更改的内容:

  • 元素中删除
    {…attributes}
    ,或从
    defaultProps
  • 元素上的
    属性更改为
    htmlFor
  • 元素中删除
    onClick
    事件

  • 嗯,似乎没有解决这个问题,我会编辑我的问题,以免混淆其他人:我把你的东西应用到我的代码中,现在我看到当我显示我的复选框时(它是隐藏的,所以我可以按我的方式设置样式),我可以检查它,它工作正常,现在我需要将它正确链接到标签上,这样它将在标签上进行检查单击:D我将尝试找出它,但我想知道你是否也可以分享一些关于它的信息:当我单击标签时,我发现了以下内容它不检查,但它切换检查(如果标签被选中,我不能选中复选框),所以我们正在做一些事情,另外,当我选中chackbox时,标签(样式为chackbox)也会交互(css更改为label:checked)我让它工作了,谢谢我从标签中删除了htmlFor,它工作了correctly@PatrykGąsior查看我的答案-您实际上不必删除
    htmlFor
    ,您可以使用它来替换
    onClick
    事件,这是React的cleanerRecommended教程系列:看起来你已经解决了这个问题,但我已经在我的答案中解释了为什么会发生一些奇怪的事情。查看:)是的,thaks,这也是我所需要的,能够澄清一些事情的人,非常感谢:我想不是这样,问题仍然存在,我将用您的解决方案编辑我的问题。感谢提供的信息,但对于第二个问题,我测试了这个解决方案,我认为在组件中使用它是不明智的。让我解释一下为什么(如果我错了,请纠正我),当我使用其中两个时,我需要为它们分配不完全相同的ID,如checkbox-1 checkbox-2等。我看不出这有什么问题,这可以动态地进行,但现在我认为这对