2017-10-20 44 views
0

我有同样的的className多个元素,我想,如果被点击的一些元素(类名历史的节点)它应该得到的className 活跃与当前的className一起。传递只有点击元素的onClick功能 - reactjs

但是我有一个问题,那个元素有子元素,如果子元素被点击,他们也得到类活动

下面是代码:

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

我想运行功能,当元素在用户点击与类名历史的节点

但如果用户点击历史标题,ClickHandler给出类活动历史标题元素。

预期行为:如果点击历史节点,则只有历史节点应获得类活动

回答

3

一个技巧,以及如何解决你的问题(在两种方式)

提示:通常不与jQuery混合React最好的主意。 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(实际正在侦听事件的元素)。

现在的代码:

有JQ

组件:

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

的作出反应的方式(纯反应,没有模块)

组件:

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

注意到你怎么不需要操作DOM在在阵营的解决方案的任何时刻。您只需将您的事件附加到该特定组件,定义状态更改应如何反映在UI上,然后让React完成剩下的工作。

希望它帮助;)

Reference for target vs currentTarget

+1

很好的解释,但是,非常感谢你的时间和精力 我得到它的工作。 –

+0

欢迎你,兄弟,很高兴它帮助 –

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状态可以避免这种情况!

+0

NOP,它不工作。行为是一样的。 :( –

+0

你可以用整个组件编辑你的原始文章吗? – 3Dos

+0

是的,这里是一个[粘贴](https://pastebin.com/qcNk9nzY) –