stopPropagation не работает в иерархии компонентов - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь избежать события onClick, которое происходит в каждой конкретной строке, всякий раз, когда нажимается show / less под данными одного столбца. У меня есть сетка, которая в основном имеет выбор, и функции множественного выбора. Также есть показать больше / показать меньше для одного столбца. Всякий раз, когда я нажимаю Show More/Less, выбор строки срабатывает. Я хочу избежать этого. Может кто-нибудь сказать, что здесь не так. скажем, если есть несколько экземпляров одинаковых сеток, я бы хотел, чтобы функциональность выбора строки в той сетке, в которой есть опора

Песочница: https://codesandbox.io/s/react-table-row-table-alternate-single-row-working-5fr81

 import * as React from "react";
import ReactTable from "react-table";
import "react-table/react-table.css";

export default class DataGrid extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedRows: []
    };
  }

  rowClick = (state, rowInfo) => {
    if (rowInfo) {
      let selectedRows = new Set();
      return {
        onClick: e => {
          e.stopPropagation();
          if (e.ctrlKey) {
            selectedRows = this.state.selectedRows;
            rowInfo._index = rowInfo.index;
            if (
              selectedRows.filter(row => row._index === rowInfo._index)
                .length === 0
            )
              selectedRows.push(rowInfo);
            else
              selectedRows = selectedRows.filter(
                row => row._index !== rowInfo._index
              );
            this.setState({
              selectedRows
            });
          } else {
            selectedRows = [];
            rowInfo._index = rowInfo.index;
            selectedRows.push(rowInfo);
          }
          this.setState(
            {
              selectedRows
            },
            () => {
              console.log("final values", this.state.selectedRows);
              this.props.rowClicked(this.state.selectedRows);
            }
          );
        },
        style: {
          background:
            this.state.selectedRows.some(e => e._index === rowInfo.index) &&
            "#9bdfff"
        }
      };
    } else {
      return "";
    }
  };

  render() {
    return (
      <ReactTable
        data={this.props.data}
        columns={this.props.columns}
        getTrProps={this.rowClick}
      />
    );
  }
}

1 Ответ

2 голосов
/ 07 января 2020

В вашем компоненте ShowMore вы можете изменить обработчик событий onClick так, чтобы он вызывал event.stopPropagation(). Это остановит дальнейшее распространение текущего события в фазах захвата и всплытия и позволит вам нажать Показать больше / меньше без запуска выбора строки.

const toggleTruncate = (e) => {
  e.stopPropagation();
  setShowMore(!isShowMore);
}

React фактически определяет событие syntheti c, который будет доступен в вашем обработчике событий click, без необходимости вызывать document.addEventListener(). Вы можете прочитать больше об обработке событий в React через здесь .

И ответить на вашу вторую часть вопроса, учитывая, что событие rowClicked является необязательным реквизитом компонента DataGrid вам нужно будет вручную проверить его на компоненте DataGrid, чтобы убедиться, что он будет вызываться только в том случае, если он определен. Вот как это можно сделать:

if (rowClicked) {
 // do the rest
}

И так должен выглядеть ваш метод rowClick. Обратите внимание, что у меня деструктурированный объект реквизита во второй строке. Это обеспечит выполнение логи выбора строки c, только если определено rowClicked.

rowClick = (state, rowInfo) => {
  const { rowClicked } = this.props;
  if (rowInfo && rowClicked) {
    let selectedRows = new Set();
    return {
      onClick: e => {
        e.stopPropagation();
        if (e.ctrlKey) {
          selectedRows = this.state.selectedRows;
          rowInfo._index = rowInfo.index;
          if (
            selectedRows.filter(row => row._index === rowInfo._index)
              .length === 0
          )
            selectedRows.push(rowInfo);
          else
            selectedRows = selectedRows.filter(
              row => row._index !== rowInfo._index
            );
          this.setState({
            selectedRows
          });
        } else {
          selectedRows = [];
          rowInfo._index = rowInfo.index;
          selectedRows.push(rowInfo);
        }
        this.setState(
          {
            selectedRows
          },
          () => {
            rowClicked(this.state.selectedRows);                
          }
        );
      },
      style: {
        background:
          this.state.selectedRows.some(e => e._index === rowInfo.index) &&
          "#9bdfff"
      }
    };
  } else {
    return "";
  }
};
...