防止触发多个 on-click 事件:ReactJS

Prevent multiple on-click events from firing: ReactJS

我有这样一种情况,我在列 header 上触发了多个点击事件。将有一个事件用于过滤器下拉列表,另一个事件用于排序。有一个过滤器图标 ,单击该图标将显示列过滤器选项。点击 header,排序也应该发生。

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

单击过滤器图标时,应仅触发过滤器处理程序

不胜感激。

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

Parent

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


你只需要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