单独onClick整个组件和组件中的按钮

时间:2018-06-13 05:36:44

标签: javascript reactjs

所以我正在创建一个用React编写的待办事项列表。我有一个功能组件ListItem,它使用任务和垃圾按钮呈现<li>元素。

我当前的功能:当用户点击实际文本时,文本会被删除,当他们点击垃圾按钮时,ListItem会被删除。

function ListItem(props) {
  return (
    <li class="list-item"}>
      <span class="item-name font" onClick={props.handleItem}>
        {props.value}
      </span>
      <button id="trash-button" onClick={props.handleTrash}>
        Trash
      </button>
    </li>
  );
}

我希望自己的功能是什么:当用户点击<li>项目中的任意位置(不包括垃圾按钮)时,文字会被删除,当他们点击垃圾箱时按钮ListItem被删除。

我认为我可以通过将handleItem onClick转移到<li>项来实现上述目标。

function ListItem(props) {
  return (
    <li class="list-item" onClick={props.handleItem}>
      <span class="item-name font">
        {props.value}
      </span>
      <button id="trash-button" onClick={props.handleTrash}>
        Trash
      </button>
    </li>
  );
}

然而,最终发生的事情是,即使单击垃圾按钮,handleItem函数也会与handleTrash函数一起被调用。有没有办法在调用handleItem时抑制handleTrash函数?

提前致谢!

编辑:我的Todo列表的完整代码。接受任务的表单称为AddEntry,并且与其他所有内容分开,因此我不包含该内容。

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import AddEntry from './AddEntry'

function ListItem(props) {
  return (
    <li class="list-item" onClick={props.handleItem}>
      <span class="item-name font">
        {props.value}
      </span>
      <button id="trash-button" onClick={props.handleTrash}>
        Trash
      </button>
    </li>
  );
}


class TodoList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      entries: []
    };

    this.handleItem = this.handleItem.bind(this);
    this.handleTrash = this.handleTrash.bind(this);
    this.handleAdd = this.handleAdd.bind(this);
  }

  renderListItem(e) {
    if(e.struck) {
      return (
        <ListItem
          key={e.key}
          value={<strike>{e.item}</strike>}
          handleTrash={() => this.handleTrash(e)}
          handleItem={() => this.handleItem(e)}
        />
      );
    }

    else {
     return(
      <ListItem
          key={e.key}
          value={e.item}
          handleTrash={() => this.handleTrash(e)}
          handleItem={() => this.handleItem(e)}
        />
      );
    }
  }

  handleAdd(e) {
    const entries = this.state.entries;
    entries.push({item: e, struck: false, key: entries.length});
    this.setState({
      entries: entries
    });
  }

  handleTrash(e) {
    const entries = this.state.entries;
    for(let i = 0; i < entries.length; i++) {
      if(entries[i] === e) {
        entries.splice(i, 1);
      }
    }

    this.setState({
      entries: entries
    });
  }

  handleItem(e) {
    console.log("hi");
    const entries = this.state.entries;
    let index = entries.findIndex(ele => e.key === ele.key);
    entries[index].struck = !entries[index].struck;
    this.setState({
      entries: entries
    });
  }

  render() {
    return (
      <div class="todo-list">
          <AddEntry handleAdd={this.handleAdd}/>
          <ul>{this.state.entries.map((e) => this.renderListItem(e))}</ul>
      </div>
    );
  }

}


ReactDOM.render(
  <TodoList />,
  document.getElementById('root')
);

this is how it's working with the onClick in the li element

1 个答案:

答案 0 :(得分:1)

保持on li本身,并在handleTrash函数中使用preventPropogation来停止传播。

 handleTrash(event){
   event.stopPropagation();
   // code the rest
}

这是一个工作示例https://codesandbox.io/s/1vqwo4j0yl