仅将单击的元素传递给onClick函数 - reactjs

时间:2017-10-20 12:27:57

标签: javascript jquery reactjs

我有多个具有相同 className 的元素,我想要点击某个元素(带有className history-node ),它应该得到className active 以及当前的className。

但是我遇到了一个问题,那个元素有孩子,如果点击了子元素,他们也会上课活跃

以下是代码:

<div className="history-node-container" key={index}>
  <div className="history-node" onClick={(e) => {this.handleHistoryClick(e.target)}}>
    <span className="history-title">{heading.action}</span>
    <span className="history-date">{moment(heading.added_at).format("MMMM Do, YYYY")}</span>
  </div>
</div>

handleHistoryClick 功能

handleHistoryClick(target){
  $('.history-node').removeClass('active'); //removing active class from all elements
  target.className = 'history-node active';
}

我想在用户点击className history-node

的元素时运行函数

但是,如果用户点击历史标题,则ClickHandler会将活动类提供给 history-title 元素。

预期行为:如果单击历史节点,则只有history-node应该为class 活动

2 个答案:

答案 0 :(得分:3)

一个提示以及如何解决您的问题(以两种方式)

提示:通常最好将ReactjQuery混合使用。 React作为我们与DOM交互的主要范式转变而来。尝试阅读更多关于React的信息,它是如何工作的,为什么它与使用jQ简单地添加/删除DOM中的元素有很大的不同。

一些参考资料可以帮助您:

How to go from jQuery to React.js?

Thinking in React for jQuery Programmers

现在,回到你的问题

您应该使用currentTarget

由于.history-title.history-date元素包含在.history-node中,所以点击它们会触发它的父级事件,因为.history-node正文为.history-title + .history-date。这是正确的行为。当您在JS中触发事件时,event对象会收到两个参数:target,即触发事件的事件和currentTarget,即实际侦听事件的元素。 / p>

现在代码:

组件:

<div className="history-node-container" key={index}>
  <div className="history-node" onClick={handleHistoryClick}>
    <span className="history-title">{heading.action}</span>
    <span className="history-date">{moment(heading.added_at).format("MMMM Do, YYYY")}</span>
  </div>
</div>

点击:

handleHistoryClick(event){
  $('.history-node').removeClass('active')
  event.currentTarget.classList.add('active')
}

React方式(Pure React,无模块)

组件:

class HistoryNode extends Component {
    constructor(props) {
        super(props)
        this.state = { isActive: false }
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick(e) {
      let state = this.state
      this.setState({isActive: !state.isActive})
    }

    render() {
      return(
        <div className="history-node-container">
          <div className={`history-node ${this.state.isActive ? 'active' : ''}`} onClick={handleHistoryClick}>
            <span className="history-title">{heading.action}</span>
            <span className="history-date">
               {moment(heading.added_at).format("MMMM Do, YYYY")}</span>
          </div>
        </div>
      )
    }
}

请注意,您无需在React解决方案中随时操纵DOM。您只需将事件附加到该特定组件,定义状态更改应如何反映在UI上,让React完成剩下的工作。

希望它有所帮助;)

Reference for target vs currentTarget

答案 1 :(得分:1)

我认为事件会传播到子组件。

你试过这个吗?

<div className="history-node-container" key={index}>
  <div className="history-node" onClick={handleHistoryClick}>
    <span className="history-title">{heading.action}</span>
    <span className="history-date">{moment(heading.added_at).format("MMMM Do, YYYY")}</span>
  </div>
</div>

HandleClick功能

handleHistoryClick(event){
  event.stopPropagation();
  $('.history-node').removeClass('active');
  event.target.className = 'history-node active';
}
编辑:你可以使用你的组件状态使它更简单(并且没有jQuery)。但是在不知道你如何编写组件的情况下,我无法给你一个说明它的片段。当您直接与DOM交互时要小心,这意味着性能损失。使用React状态可以避免这种情况!