我有一个问题,我的自定义复选框不起作用, 我对 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
即可。这是最终代码:
总而言之,以下是要更改的内容:
- 从
<input>
元素中删除{...attributes}
或从defaultProps
中删除checked
- 将
for
属性更改为<label>
元素上的htmlFor
- 从
<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>