我有一个问题,我的自定义复选框不起作用, 我对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;
问题在于此组件未得到检查,但是如果我将state设置为true,则不会取消选中该组件,如果我将控制台日志安装到handleChange或handleClick,则单击时会得到console.logged,但仅适用于第一次点击,我不确定这是什么意思。我在这里的另一篇文章中提到,单击并取消选中可能会出现问题,因此我创建了一个无限循环,但是在这种情况下,我认为应该有一个console.logs无限循环。 如果我的代码是完全错误的,请随意编辑它,但是如果它没有太多麻烦,请尝试为我注释一下已更改的部分,以便我更好地了解发生了什么:D
谢谢。
答案 0 :(得分:2)
欢迎来到stackoverflow:)
我认为您的问题出在
handleChange() {
this.setState({'checked' : this.state.checked});
}
您不需要更改状态,而只是想再次使用相同的值进行设置。将其更改为:
handleChange() {
this.setState({'checked' : !this.state.checked});
}
编辑:
因此,有关输入未从选中更改为未选中的真正问题是将{...attributes}
移交给了输入。这似乎与“ checked”属性有关,该属性会干扰输入元素的默认选中值。
此外,在使用react时,应使用htmlFor
属性而不是for
。
答案 1 :(得分:1)
第一个问题是您正在checked: false
中设置默认道具defaultProps
,并且始终通过input
在{...attributes}
上设置此道具,所以您有效地总是将该值写为false,这就是为什么状态更改没有任何区别的原因。
要解决此问题,您可以放弃该默认属性(也可以摆脱在componentDidMount
中设置状态),也可以停止将所有attributes
数据丢入{{1} }元素的默认值。由你决定。
现在,您应该可以看到该复选框已选中/未选中。
关于将input
元素上的属性for
更改为htmlFor
,实际上这实际上会将label
元素绑定到label
,所以您无需为input
实现onClick
处理程序。因此,一旦您修复了此属性,就完全摆脱label
上的onClick
。这是最终的代码:
总而言之,这是要更改的内容
label
元素中删除{...attributes}
,或者从<input>
中删除checked
defaultProps
元素上的for
属性更改为htmlFor
<label>
元素中删除onClick
事件答案 2 :(得分:-1)
这也是一个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>