首页 > 解决方案 > 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,
};

导出默认复选框;

标签: reactjsreact-hooks

解决方案


这里的问题是你htmlForlabel. 这需要用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将单击其后代,例如buttonspan。该样式将阻止那些被点击,因此标签将成为被点击的元素,因此复选框的更改事件将触发。

编辑 runtime-river-0ow2h


推荐阅读