2017-10-20 57 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) –

相關問題