React点击/鼠标事件处理[react-sortable-hoc,material-ui,react-virtualized]

时间:2019-06-02 23:33:53

标签: reactjs typescript material-ui react-virtualized react-sortable-hoc

我有以下示例

Stackblitz Live Working Example

如果您按红色垃圾箱图标上的Delete(删除)按钮,则不会触发我的onClick事件处理程序(而是立即开始排序)。

如果您按下按钮的删除按钮背景(在垃圾桶图标周围的圆圈),它将触发按钮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 个答案:

答案 0 :(得分:1)

我正在处理同一种应用程序,当我单击单元格上的东西并使它们可排序时,我想执行一些操作。可以通过两种方式实现

  1. 添加延迟道具press SortableContainer HOC中的延迟道具。 docs 假设 pressDelay = 500 。这样做是,如果您将点击保持500ms,则该行将变为可排序的,否则将触发常规的click事件。在我看来,这将很好地工作

2.add在行首添加句柄,仅通过拖动句柄就可以对其进行排序。为此,您需要实现customTableRowRenderer。只需从此处rowRenderer复制代码,并从可排序的hoc导入Handle,然后更改返回函数

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

不要忘记将Handle添加为第一列。