为什么我的 React 应用程序中的两个点击事件会同时发生 运行?

Why do my two click events in my React app run at the same time?

我有两个用户设置选项。一个是“启用层叠面板”,一个是“包含附件”。

我已经设置了状态变量和切换函数来传递给子组件,这样当我点击其中任何一个时,父组件就可以在值之间切换。问题是当我点击任何一个时,另一个也会执行。我是否错过了设置这些的步骤?

父组件数据:

州:

    constructor(props){
     const userToggleSettings = {
       cascadingPanels: true,
       includeAttachments: true,
       analyticsOptIn: false
     };
    
     this.state = {
       userToggleSettings
     };
    }

切换功能:


toggleIncludeAttachments = () => {
    this.setState((prevState) => (
        {
            userToggleSettings:
            {
                includeAttachments: !prevState.userToggleSettings.includeAttachments
            }
        }
    ));
};

toggleCascadingPanels = () => {
    this.setState((prevState) => (
        {
            userToggleSettings:
            {
                cascadingPanels: !prevState.userToggleSettings.cascadingPanels
            }
        }
    ));
};

includeAttachmentsClickHandler = () => {
    this.toggleIncludeAttachments();
}

cascadingPanelsClickHandler = () => {
    this.toggleCascadingPanels();
}

将值和函数作为 props 传递:

<ChildComponent
  attachmentsSwitchHandler={this.toggleIncludeAttachments}
  attachmentsSwitchValue={this.state.userToggleSettings.includeAttachments}
  cascadingPanelsSwitchHandler={this.toggleCascadingPanels}
  cascadingPanelsSwitchValue={this.state.userToggleSettings.cascadingPanels}
/>

子组件数据

在子组件中设置点击事件和值:

<div className='child-component-container'>
    <div className={'user-settings-toggle'}
        onClick={props.cascadingPanelsSwitchHandler}
    >
    <div className={'user-settings-label'}>
            {props.translations.CASCADING_PANELS}
        </div>
    <Switch
        checked={props.cascadingPanelsSwitchValue}
        translations={{
            off: props.translations.off,
            on: props.translations.ON
        }}
        />
    </div>
    <div className={'user-settings-toggle'}
      onClick={props.attachmentsSwitchHandler}
    >
    <Switch
        checked={props.attachmentsSwitchValue}
        translations={{
            off: props.translations.off,
            on: props.translations.ON
        }}
    />
    <div className={'user-settings-label'}>
        {props.translations.ALWAYS_INCLUDE_ATTACHMENTS}
    </div>
</div>

演示:

有人可以澄清我在这里做错了什么吗?

您应该这样更改您的切换功能:

 this.setState((prevState) => (
        {
            userToggleSettings:
            {
                ...prevState.userToggleSettings, // ---> added
                cascadingPanels: !prevState.userToggleSettings.cascadingPanels
            }
        }
    ));

React 不执行“深度合并”,即不合并嵌套对象。仅合并顶级属性。

因此,在执行 setState.

之后,您失去了 userToggleSettings 对象中的所有内容