Событие, передаваемое от родителя к ребенку при целевом клике - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь сделать таблицу в React и сделать строки кликабельными. Строки таблицы могут содержать ячейки с кнопками или другими интерактивными элементами, однако, если ячейка таблицы содержит интерактивный элемент, я не хочу, чтобы при щелчке элемента ячейки вызывалась функция rowClick.

По какой-то причине события распространяются в обратном направлении, чего я и ожидал. От родительского (Row) до дочернего (Cell), поэтому, когда я устанавливаю флажок в ячейке, порядок обратных вызовов onClick будет Row -> Checkbox.

Поскольку более специфичный обработчик onClick называется после функции onClick строки, я не смог отменить распространение события, как я изначально намеревался.

Я посмотрел документы MDN и отреагировал на события, но из того, что я могу сказать, событие должно выглядеть следующим образом. Cell -> Row

Я думал об использовании ссылки на строку и сравнении ее с целью, но мне не пришлось бы хранить ссылки для каждой видимой строки ...

Код строки:

<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 Ответ

1 голос
/ 27 мая 2019

Единственное, что вы можете сделать, чтобы избежать такого рода событий, - это определить случай переключения. Вы можете отфильтровать цель, вызывающую событие, по ее className, а затем применить свою логику для каждого случая.

Вот коды и окно для просмотра в действии: 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;

Child

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;
...