reactjs - handleChange 函数未在单击时触发... Reactjs 复选框
问题描述
我正在映射一组复选框,以便使用 handleChange 函数选中和取消选中复选框,但我不明白为什么它不起作用。我认为这是一个小错误,我已经达到了最大的疲劳。请把你的眼睛和思想借给我。正如他们所说,“当眼睛失明时,头脑是无用的。”
下面的代码:
/* eslint-disable react/prop-types */
/* eslint-disable no-shadow */
/** @module templates/GeoidCaculator/components/Models */
import React, { useState } from 'react';
import { Col, Row } from 'react-bootstrap';
import CheckBox from 'components/GeoidCaculator/components/CheckBox';
/**
* @description Creates the field selection view as well handles the state for the checkboxes.
* @param {}
* @returns {Object} Returns Fields jsx.
*/
function Models() {
const [check, setCheck] = useState({});
/**
* @description Handles the state for the checkboxes.
* @param {event}
* @returns {Object} Returns boolean values.
*/
const handleChange = (event) => {
setCheck({ ...check, [event.target.name]: event.target.checked });
console.log('check: ', check);
};
const checkboxes = [
{
name: ' 2020',
key: 'checkBox1',
label: '-2020',
},
{
name: ' 2008',
key: 'checkBox2',
label: '-2008',
},
{
name: ' 1996',
key: 'checkBox3',
label: '-1996',
},
{
name: ' 1984',
key: 'checkBox4',
label: '-1984',
},
];
console.log(checkboxes.map((item) => item.key), handleChange, 'hello render');
return (
<Col className="col-sm-offset-3 col-md-offset-2 main">
<Row className="modelText">
<span>Select a Model:</span>
</Row>
{checkboxes.map((item) => (
<Row className="modelRow">
<label
key={item.key}
htmlFor="model-id"
className="checkbox-inline checkbox-styled checkbox-success"
>
<button type="button">
<CheckBox name={item.name} checked={check[item.name]} onChange={handleChange} />
<span>{item.name}</span>
</button>
</label>
</Row>
))}
</Col>
);
}
export default Models;
/** @module templates/GeoidCaculator/components/CheckBox */
import React from 'react';
import PropTypes from 'prop-types';
/**
* @description Creates the checkbox inputs and sets initial state.
* @param {sting} type - declares checkbox
* @param {sting} name - declares name
* @param {boolean} checked - boolean value to check/uncheck box
* @param {Event} onChange - hanldes change
* @returns {Object} Returns input jsx.
*/
const CheckBox = ({
type, name, checked, onChange,
}) => (
<input type={type} name={name} checked={checked} onChange={onChange} />
);
CheckBox.propTypes = {
type: PropTypes.string,
name: PropTypes.string.isRequired,
checked: PropTypes.bool,
onChange: PropTypes.func.isRequired,
};
CheckBox.defaultProps = {
type: 'checkbox',
checked: false,
};
导出默认复选框;
解决方案
这里的问题是你htmlFor
对label
. 这需要用id
一个input
字段映射。请参阅此处:https ://developer.mozilla.org/en-US/docs/Web/HTML/Element/label 。
因此,为此,我建议重构您的CheckBox
组件,使其也接受一个id
道具(您也可以选择使用而不是作为道具key
传递)。id
const CheckBox = ({ id, type, name, checked, onChange }) => (
<input id={id} type={type} name={name} checked={checked} onChange={onChange} />
);
同样,在映射时,htmlFor
值需要与其对应input
的字段合作。
<label
key={item.key}
htmlFor={item.key}
className="checkbox-inline checkbox-styled checkbox-success"
onClick={(e) => {
e.target.closest("label").click();
}}
>
<button type="button" style={{pointerEvents: "none"}}>
<CheckBox
id={item.key}
type="checkbox"
name={item.name}
checked={check[item.name]}
onChange={handleChange}
/>
<span>{item.name}</span>
</button>
</label>
最后,注意 的style
道具button
。单击label
将单击其后代,例如button
或span
。该样式将阻止那些被点击,因此标签将成为被点击的元素,因此复选框的更改事件将触发。