React 复选框不会将其状态设置为在标签单击时选中



我有一个问题,我的自定义复选框不起作用, 我对 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;

问题是这个组件没有得到检查,但是如果我将状态设置为 true,它不会取消选中,如果我将控制台日志安装到 handleChange 或 handleClick,当我单击时我会得到 console.log,但仅限于第一次点击,我不确定这意味着什么。在这里的另一篇文章中,我红了,单击时我检查和取消选中可能是问题,所以我创建了一个无限循环,但在这种情况下,我认为我应该有一个 console.logs 的无限循环。 如果我的代码完全错误,请随意根据需要对其进行编辑,但如果它不是很忙,请尝试为我评论更改的部分,以便我更好地了解发生了什么:D

提前谢谢。

欢迎来到 stackoverflow :)

我认为你的问题在于

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

您不会更改状态,而只是想使用相同的值再次设置它。当您将其更改为以下内容时,您应该没问题:

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

编辑:

因此,关于输入未从选中更改为未选中的真正问题是将{...attributes}移交给输入。这似乎与"checked"属性相关联,该属性会干扰输入元素的默认检查值。

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

第一个问题是你在defaultProps中设置了一个默认的 propchecked: false,并且这个 prop 总是通过{...attributes}input上设置,所以你实际上总是将该值写入 false,这就是为什么状态更改没有任何区别。

要解决此问题,您可以摆脱该默认 prop(也可以摆脱在componentDidMount中设置状态),或者您可以默认停止将所有attributes数据扔到input元素中。轮到你了。

现在您应该能够看到复选框被选中/取消选中。

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

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

  1. <input>元素中删除{...attributes}defaultProps中删除checked
  2. for属性更改为<label>元素上的htmlFor
  3. <label>元素中删除onClick事件

这也是一个HTML问题,您必须将标签与输入链接在一起,以便它们一起触发,请参阅下面的解决方案,这也可能有助于(https://www.w3schools.com/tags/tag_label.asp)

<h1>checkbox demo</h1>
<input type="checkbox">
<label>I don't activate the checkbox</label>
<hr>
<input type="checkbox" id="checkbox_1">
<label for="checkbox_1">I activate the checkbox</label>
<hr>
<label>
	<input type="checkbox">
	I also activate the checkbox
</label>

最新更新