反应,为什么标签不触发复选框的 onChange?

Mar*_* P. 5 html javascript checkbox reactjs

我觉得我已经做了一百万次,但可能不是用映射函数。我有一系列活动,我正在使用代码创建复选框,如下所示(__map顺便说一下来自 Lodash):

<div className="activity-blocks">
{
    __map(this.state.activities, (activity, i) => {
        return (
            <div key={ i } className="single-activity">
                <input id={ `register-activity-${ i }` } 
                    type="checkbox" className="register-multiselect" 
                    name="main_activity" checked={ !!activity.checked } 
                    onChange={ (e) => this.toggleActivity(e, activity.id) }
                />
                <label htmlFor={ `register-activity-${ i }` }>{ activity.name }</label>
            </div>
         )
    })
 }
Run Code Online (Sandbox Code Playgroud)

我的onChange处理程序看起来像这样:

toggleActivity(e, activityId) {
    let activities = { ...this.state.activities };

    __forEach(this.state.activities, (activity) => {
        if (activityId === activity.id) {
            activity = __assign(activity, { checked: e.target.checked });
            return false;
        }
    });

    this.setState({ activities: activities });
}
Run Code Online (Sandbox Code Playgroud)

处理程序工作得很好,主要供参考。我的问题是标签没有触发处理程序。我只测试了没有标签的复选框输入,它会触发处理程序。有谁知道为什么标签不这样做?

更多信息:我以前遇到过这个问题,但结果通常是 id 不匹配或类似的简单问题。我不相信这一次。


编辑 我已经从我的文件中删除了几乎所有的代码,并在下面加入了 Slawa 的答案,但它仍然没有按预期运行。这是包含所有导入、类结构和所有不必要的代码(包括样式)的代码:

import React from 'react';
import __forEach from 'lodash/forEach';
import __assign from 'lodash/assign';
import __map from 'lodash/map';

export default class RegisterActivities extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            activities: [
                {
                    id: 1,
                    name: 'label-1'
                },
                {
                    id: 2,
                    name: 'label-2'
                },
                {
                    id: 3,
                    name: 'label-3'
                }
            ],
        }
    }

    toggleActivity(e, activityId) {
        const { activities } = this.state;

        const updated = activities.map((activity) => {
            if (activity.id === activityId){
                return {
                    ...activity,
                    checked: e.target.checked
                }
            }

            return activity;
        });
    }

    render() {
        return (
            <div>
                <p>what do you do?</p>
                <div>
                {
                    __map(this.state.activities, (activity, i) => {
                        return (
                            <div key={ i }>
                                <input id={ `register-activity-${ i }` } 
                                    type="checkbox" 
                                    name="main_activity" checked={ !!activity.checked } 
                                    onChange={ (e) => this.toggleActivity(e, activity.id) }
                                />
                                <label htmlFor={ `register-activity-${ i }` }>{ activity.name }</label>
                            </div>
                        )
                    })
                }
                </div>
            </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

Edit2 我正在玩,决定更换onChangeonClick现在我可以点击实际的复选框来点击toggleActivity. 有没有人知道为什么 onChange 没有触发?

Mar*_* P. 4

我的问题的答案可以在这篇 SO 帖子中找到。事实证明,我的标签onClick事件(在 html/React 的幕后,不是我自己编码的)正在冒泡到父级,而不是处理输入。我需要告诉厂牌停止通过这样做进行传播onClick={ e => e.stopPropagation() }