防止触发多个点击事件:ReactJS

时间:2019-07-30 06:26:55

标签: javascript reactjs ecmascript-6 dom-events setstate

我遇到的情况是,我在列标题上触发了多个单击事件。将有一个事件用于过滤器下拉列表,另一事件用于排序。有一个过滤器图标,在其上单击将显示列过滤器选项。在单击标题时,也应进行排序。

现在,每当我单击过滤器图标时,两个处理程序都会被解雇。有人可以帮我弄这个吗。

点击过滤器图标后,只有过滤器处理程序应该触发

我们将不胜感激。

沙箱:https://codesandbox.io/s/relaxed-feather-xrpkp

父母

import * as React from "react";
import { render } from "react-dom";
import ReactTable from "react-table";
import "./styles.css";
import "react-table/react-table.css";
import Child from "./Child";
interface IState {
  data: {}[];
  columns: {}[];
}

interface IProps {}

export default class App extends React.Component<IProps, IState> {
  constructor(props: any) {
    super(props);
    this.state = {
      data: [
        { firstName: "Jack", status: "Submitted", age: "14" },
        { firstName: "Simon", status: "Pending", age: "15" },
        { firstName: "Pete", status: "Approved", age: "17" }
      ],
      columns: []
    };
  }

  handleColumnFilter = (value: any) => {
    console.log(value);
  };

  sortHandler = () => {
    console.log("sort handler");
  };

  componentDidMount() {
    let columns = [
      {
        Header: () => (
          <div onClick={this.sortHandler}>
            <div style={{ position: "absolute", marginLeft: "10px" }}>
              <Child handleFilter={this.handleColumnFilter} />
            </div>
            <span>First Name</span>
          </div>
        ),
        accessor: "firstName",
        sortable: false,
        show: true,
        displayValue: " First Name"
      },
      {
        Header: () => (
          <div onClick={this.sortHandler}>
            <span>Status</span>
          </div>
        ),
        accessor: "status",
        sortable: false
      }
    ];
    this.setState({ columns });
  }

  render() {
    const { data, columns } = this.state;
    return (
      <div>
        <ReactTable
          data={data}
          columns={columns}
          defaultPageSize={10}
          className="-striped -highlight"
        />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

过滤器组件

import * as React from "react";
import { Icon } from "semantic-ui-react";
import "./styles.css";
interface IProps {
  handleFilter(val1: any): void;
}
interface IState {
  showList: boolean;
}
export default class Child extends React.Component<IProps, IState> {
  constructor(props: any) {
    super(props);
    this.state = {
      showList: false
    };
  }

  toggleList = () => {
    console.log("filter handler");
    this.setState(prevState => ({ showList: !prevState.showList }));
  };

  render() {
    let { showList } = this.state;
    let visibleFlag: string;
    if (showList === true) visibleFlag = "visible";
    else visibleFlag = "";
    return (
      <div>
        <div style={{ position: "absolute" }}>
          <div
            className={"ui scrolling dropdown column-settings " + visibleFlag}
          >
            <Icon className="filter" onClick={this.toggleList} />
          </div>
        </div>
      </div>
    );
  }
}


1 个答案:

答案 0 :(得分:2)

您只需要event.stopPropagation()。这会将事件隔离到仅此特定执行块。因此,现在当您单击过滤器图标时,它将仅触发指定的事件处理程序。

  toggleList = (event) => {
    event.stopPropgation()
    console.log("filter handler");
    this.setState(prevState => ({ showList: !prevState.showList }));
  };

您还需要在这里使用它:

  handleValueChange = (event: React.FormEvent<HTMLInputElement>, data: any) => {
    event.stopPropagation()
    let updated: any;
    if (data.checked) {
      updated = [...this.state.selected, data.name];
    } else {
      updated = this.state.selected.filter(v => v !== data.name);
    }
    this.setState({ selected: updated });
  };

在这里:

 passSelectionToParent = (event: any) => {
    event.preventDefault();
    event.stopPropagation()
    this.props.handleFilter(this.props.name, this.state.selected);
  };

从字面上看,只要您具有父标记的点击事件并且它具有也具有单击事件的子标记,则可以使用event.stopPropagation()来停止触发父点击事件。

这是沙箱:https://codesandbox.io/s/elated-gauss-wgf3t