目标点击使事件从父级冒到子级

时间:2019-05-26 22:39:08

标签: reactjs jsx dom-events

我正在尝试在React中渲染表格并使行可点击。表格行可能包含具有按钮或其他可点击元素的单元格,但是如果表格单元格包含可点击元素,我不希望在单元格元素被单击时调用行onClick函数。

由于某种原因,这些事件与我所期望的相反。从父级(行)到子级(单元格),因此当我单击单元格中的复选框时,onClick回调的顺序为行->复选框。

因为更具体的onClick处理程序在行的onClick函数之后称为 ,所以我一直无法取消最初打算的事件传播。

我已经查看了MDN中的文档并对事件做出了反应,但据我所知,事件应按如下顺序排序:单元格->行

我考虑过在行中使用ref并将其与目标进行比较,但宁愿不必为可见的每一行存储ref ...

行代码:

<TableRow 
    key={keyedItem.key}
    selected={this.isItemSelected(keyedItem.key)}
    hover={true} 
    onClick={(event) => this.handleRowClicked(event, keyedItem)}
>
    {this.renderCheckBox(keyedItem.key)}
    {this.props.renderRowCells(keyedItem.item)}
</TableRow>

上方的renderCheckbox(key)函数

private renderCheckBox(key: string) {
        if (this.multiSelectionMode()) {
            return (
                <TableCell padding="checkbox">
                    <Checkbox
                        checked={this.isSelected(key)}
                        onChange={(event, checked: boolean) => { console.log(event.target); this.changeItemSelection(key, checked); }}
                   />
                </TableCell>
            );
        }
        return null;
    }

有人知道我在这里做错什么吗?还是按预期工作?

1 个答案:

答案 0 :(得分:0)

防止这种事件冒泡的一件事是定义一个开关盒。您可以通过其类名过滤导致事件的目标,然后对每种情况应用逻辑。

以下是一个代码框,供您查看实际使用情况:https://codesandbox.io/s/sparkling-waterfall-u7b87

父母

import React from "react";
import Child from "./Child";

class Parent extends React.Component {
  state = {
    cells: [
      { value: 1, selected: false },
      { value: 2, selected: false },
      { value: 3, selected: false }
    ]
  };
  handleClickEvents = event => {
    var target = event.target.className;
    switch (target) {
      case "parent":
        return console.log(target);
      case "child":
        return this.findCheckedInput(event);
      default:
        return;
    }
  };

  findCheckedInput = event => {
    const updatedCells = this.state.cells.map(cell => {
      if (cell.value == event.target.value) {
        return {
          ...cell,
          selected: !cell.selected
        };
      } else {
        return cell;
      }
    });

    this.setState(
      {
        cells: updatedCells
      },
      () => console.log(this.state)
    );
  };

  renderChildren = () => {
    const { cells } = this.state;
    return cells.map(item => {
      return (
        <Child
          key={item.value}
          handleClick={this.handleClickEvents}
          value={item.value}
          selected={item.selected}
        />
      );
    });
  };

  render() {
    return (
      <div
        className="parent"
        style={{ background: "green" }}
        onClick={this.handleClickEvents}
      >
        {this.renderChildren()}
      </div>
    );
  }
}

export default Parent;

孩子

import React from "react";

class Child extends React.Component {
  handleOnClick = () => {
    this.props.handleClick();
  };

  render() {
    return (
      <input
        className="child"
        onChange={this.handleOnClick}
        type="checkbox"
        checked={this.props.selected}
        value={this.props.value}
      />
    );
  }
}

export default Child;