Обработка событий React Click / Mouse [реагировать-сортировать-hoc, материал-интерфейс, реагировать-виртуализировать] - PullRequest
0 голосов
/ 03 июня 2019

У меня есть следующий пример

Пример работы в реальном времени Stackblitz

Если вы нажмете кнопку удаления на красном значке корзины, мой обработчик событий onClick не сработает (вместо этого сортировка начнется сразу).

Если вы нажмете кнопку удаления на заднем плане кнопки (обведите вокруг значка корзины), она запустит обработчик кнопки onClick и будет действовать соответственно.

Я пробовал ставить разные клики (включая xxxxCapture версии и e.preventDefault()), но безуспешно.

Вопросы

Поэтому у меня есть 2 вопроса:

  1. Есть ли хороший способ выяснить, где в дереве впервые обрабатывается щелчок?
  2. Как сделать так, чтобы моя кнопка onClick была одинаковой по всему фону, а также сама icon?

Код

Для тех, кто не может открыть Stackblitz, код:

import React from 'react';
import { Button, IconButton, Tooltip, Typography } from "@material-ui/core";

import { Add, DeleteForever } from "@material-ui/icons";
import { AutoSizer, Column, Index, Table, TableCellProps, TableProps, TableRowProps, WindowScroller, defaultTableRowRenderer } from "react-virtualized";
import { SortableContainer, SortableElement, SortEnd, SortEndHandler, SortEvent } from "react-sortable-hoc";


import 'react-virtualized/styles.css';

const SortableTable = SortableContainer<TableProps>((props: TableProps) => (
  <Table {...props} />
));

const SortableRow = SortableElement<TableRowProps>(
  (props: TableRowProps) => defaultTableRowRenderer(props) as any
);

const sortableRowRenderer = (props: TableRowProps) => {
  return <SortableRow {...props} />;
};

interface IRow {
  value: string;
}

class Grid extends React.Component<any, { items: IRow[] }> {

  remove(rowData: any): any {
    const items = this.state.items;

    if (!items) {
      return;
    }

    const index = items.indexOf(rowData);

    const newItems = [...items.slice(0, index), ...items.slice(index + 1)];

    this.setState({ items: newItems });
  }

  constructor(props: any) {
    super(props);

    this.state = {
      items: this.getDefaultItems()
    };
  }

  private getDefaultItems = () => {
    return [
      { value: "one" },
      { value: "two" },
      { value: "three" },
      { value: "four" },
      { value: "five" }
    ]
  }

  private rowRenderer = (props: TableRowProps) => {
    return defaultTableRowRenderer(props);
  };

  public render() {
    return (
      <div>
        <WindowScroller>
          {({ height, isScrolling, onChildScroll, scrollTop }) => (
            <AutoSizer disableHeight={true}>
              {size => (
                <SortableTable
                  headerHeight={38}
                  autoHeight={true}
                  height={height}
                  rowCount={this.state.items.length}
                  scrollTop={scrollTop}
                  rowGetter={this.getItem}
                  rowHeight={37}
                  width={size.width}
                  rowRenderer={sortableRowRenderer}
                >
                  <Column label={"value"} dataKey={"value"} width={160} />
                  <Column
                    dataKey={"buttons"}
                    cellRenderer={this.buttonsCellRenderer}
                    width={48}
                    minWidth={48}
                    maxWidth={48}
                  />
                </SortableTable>
              )}
            </AutoSizer>
          )}
        </WindowScroller>
        <Button onClick={this.reset}>Reset</Button>
      </div>
    );
  }

  private reset = () => {
    this.setState({ items: this.getDefaultItems() });
  }

  private buttonsCellRenderer = (props: TableCellProps) => {
    const remove = (event: any) => {
      console.log("remove");
      console.log(event);

      this.remove(props.rowData);
    };

    const removeWithPrevent = (event: any) => {
      console.log("removeWithPrevent");
      console.log(event);

      this.remove(props.rowData);
    };

    return (
      <Tooltip title="Delete Line Item" enterDelay={500}>
        <IconButton onClick={remove}>
          <DeleteForever fontSize="small" color="error" onClick={remove} />
        </IconButton>
      </Tooltip>
    );
  };

  private getItem = (info: Index) => {
    const rows = this.state.items;

    const row = rows[info.index];

    return row;
  };
}

export default Grid;

1 Ответ

1 голос
/ 05 июня 2019

Я работаю над тем же типом приложений, где я хочу выполнить какую-то операцию, когда я что-то нажал на ячейку, а также сделал их сортируемыми.это может быть достигнуто двумя способами:

  1. добавить задержку prop pressDelay props в SortableContainer HOC. документы скажем pressDelay = 500 .то, что это будет делать, это то, что если вы удерживаете свой клик в течение 500 мс, строка станет сортируемой, в противном случае будет срабатывать обычное событие щелчка. По моему мнению, это будет работать очень хорошо

2.add Обрабатывать при запускеряд и сделать сортируемым, только перетаскивая ручку.Для этого вам нужно реализовать customTableRowRenderer.просто скопируйте код отсюда rowRenderer и импортируйте дескриптор из сортируемого документа и просто измените функцию возврата

  import { SortableHandle } from 'react-sortable-hoc';

     const DragHandle = SortableHandle(() => columns[0]);
      return (
        <div
          {...a11yProps}
          className={className}
          key={key}
          role='row'
          style={style}>
          <DragHandle />
          {columns.slice(1, columns.length)}
        </div>
      );

не забудьте добавить дескриптор в качестве первого столбца.

...