title: React Click/Mouse Event Handling [react-sortable-hoc, material-ui, react-virtualized]
body: <p>I have the following example</p>
  
  <p><a href="https://stackblitz.com/edit/react-sortable-hoc-material-button-click-handling-issue" rel="nofollow noreferrer">Stackblitz Live Working Example</a></p>
  
  <p>If you press the delete button on the red bin icon, it doesn't fire my <code>onClick</code> event handler (instead sorting starts straight away).</p>
  
  <p>If you press the delete button background of the button (circle around the bin icon), it fires the button <code>onClick</code> handler and acts accordingly.</p>
  
  <p>I have tried putting different onClick (including <code>xxxxCapture</code> versions and <code>e.preventDefault()</code>) but not having any success.</p>
  
  <h1>Questions</h1>
  
  <p>Therefore I have 2 questions:</p>
  
  <ol>
  <li>Is there a good way to figure out where in the tree the click is being first handled?</li>
  <li>How can I make my button <code>onClick</code> consistent across the background as well as the <code>icon</code> itself?</li>
  </ol>
  
  <h1>Code</h1>
  
  <p>For those who can't open the Stackblitz, the code is:</p>
  
  <pre><code>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&lt;TableProps&gt;((props: TableProps) =&gt; (
    &lt;Table {...props} /&gt;
  ));
  
  const SortableRow = SortableElement&lt;TableRowProps&gt;(
    (props: TableRowProps) =&gt; defaultTableRowRenderer(props) as any
  );
  
  const sortableRowRenderer = (props: TableRowProps) =&gt; {
    return &lt;SortableRow {...props} /&gt;;
  };
  
  interface IRow {
    value: string;
  }
  
  class Grid extends React.Component&lt;any, { items: IRow[] }&gt; {
  
    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 = () =&gt; {
      return [
        { value: "one" },
        { value: "two" },
        { value: "three" },
        { value: "four" },
        { value: "five" }
      ]
    }
  
    private rowRenderer = (props: TableRowProps) =&gt; {
      return defaultTableRowRenderer(props);
    };
  
    public render() {
      return (
        &lt;div&gt;
          &lt;WindowScroller&gt;
            {({ height, isScrolling, onChildScroll, scrollTop }) =&gt; (
              &lt;AutoSizer disableHeight={true}&gt;
                {size =&gt; (
                  &lt;SortableTable
                    headerHeight={38}
                    autoHeight={true}
                    height={height}
                    rowCount={this.state.items.length}
                    scrollTop={scrollTop}
                    rowGetter={this.getItem}
                    rowHeight={37}
                    width={size.width}
                    rowRenderer={sortableRowRenderer}
                  &gt;
                    &lt;Column label={"value"} dataKey={"value"} width={160} /&gt;
                    &lt;Column
                      dataKey={"buttons"}
                      cellRenderer={this.buttonsCellRenderer}
                      width={48}
                      minWidth={48}
                      maxWidth={48}
                    /&gt;
                  &lt;/SortableTable&gt;
                )}
              &lt;/AutoSizer&gt;
            )}
          &lt;/WindowScroller&gt;
          &lt;Button onClick={this.reset}&gt;Reset&lt;/Button&gt;
        &lt;/div&gt;
      );
    }
  
    private reset = () =&gt; {
      this.setState({ items: this.getDefaultItems() });
    }
  
    private buttonsCellRenderer = (props: TableCellProps) =&gt; {
      const remove = (event: any) =&gt; {
        console.log("remove");
        console.log(event);
  
        this.remove(props.rowData);
      };
  
      const removeWithPrevent = (event: any) =&gt; {
        console.log("removeWithPrevent");
        console.log(event);
  
        this.remove(props.rowData);
      };
  
      return (
        &lt;Tooltip title="Delete Line Item" enterDelay={500}&gt;
          &lt;IconButton onClick={remove}&gt;
            &lt;DeleteForever fontSize="small" color="error" onClick={remove} /&gt;
          &lt;/IconButton&gt;
        &lt;/Tooltip&gt;
      );
    };
  
    private getItem = (info: Index) =&gt; {
      const rows = this.state.items;
  
      const row = rows[info.index];
  
      return row;
    };
  }
  
  export default Grid;
  </code></pre>