2017-04-16 58 views
1

我正在使用React.js構建我的投資組合。在一節中,我將四個組件放在一個網格中。我想要做的是當單擊一個組件時,將一個css類添加到此組件的同級中,以便減少其不透明度並保留單擊的組件。在jQuery中,它會像$('。component')。on('click',function(){$(this).siblings.addClass('fadeAway')})。我怎樣才能達到這個效果?這裏是我的代碼,預先感謝任何和所有的幫助!當組件在React中單擊時將類添加到同級

class Parent extends Component{ 
    constructor(){ 
    super(); 
    this.state = {fadeAway: false} 
    this.handleClick = this.handleClick.bind(this) 
    } 
    handleClick(){ 
    //Add class to siblings 
    } 
    render(){ 
    const array = ["Hello", "Hi", "How's it going", "Good Times"] 
    return(
     array.map(function(obj, index){ 
     <Child text={obj} key={index} onClick={() => this.handleClick} /> 
     }) 
    ) 
    } 
} 

回答

1

這個問題可能是這個樣子,有一個稍微更復雜的初始化數組的工作例如:

class Parent extends Component{ 
    constructor(){ 
    super(); 
    this.state = { 
     elements: [ 
     { 
      id: "hello", 
      text: "Hello", 
      reduced: false, 
     }, 

     { 
      id: "hi", 
      text: "Hi", 
      reduced: false, 
     } 

     { 
      id: "howsItGoing" 
      text: "How's it going", 
      reduced: false, 
     } 

     { 
      id: "goodTimes", 
      text: "Good Times", 
      reduced: false, 
     } 
     ], 
    } 

    this.handleClick = this.handleClick.bind(this) 
    } 

    handleClick(e){ 
    // copy elements from state 
    const elements = JSON.parse(JSON.stringify(elements)); 
    const newElements = elements.map(element => { 
     if (element.id === e.target.id) { 
     element.reduced = false; 
     } else { 
     element.reduced = true; 
     } 
    }); 


    this.setState({ 
     elements: newElements, 
    }); 
    } 

    render(){ 
    return(
     this.state.elements.map(function(obj, index){ 
     <Child 
      id={obj.id} 
      text={obj.text} 
      reduced={obj.reduced} 
      key={index} 
      onClick={() => this.handleClick} /> 
     }); 
    ); 
    } 
} 

然後,您只需在Child組件中添加一個三元組即可:

<Child 
    id={this.props.id} 
    className={this.props.reduced ? "reduced" : ""} /> 

這增加了比其他示例更多的樣板,但將業務邏輯與組件內部的文本聯繫起來非常脆弱,而更強大的解決方案需要更強大的標識,例如渲染的DOM上的ID或類元件。如果你願意的話,這個解決方案也可以很容易地讓你擴展你的邏輯,以便一個以上的元素可以保持最大不透明度。

+0

這個解決方案實際上幫助最大。起初,它對我所做的事情似乎有點強大,但你真的解釋得很清楚,現在對我來說是完全合理的。我不得不稍微調整一下handleClick函數,並且不需要使用JSON.parse,但總體概念起作用,並且我實現了我的最終目標。謝謝!! @furkle –

+0

@IanSpringer很高興爲您服務! – furkle

0

可以實現,使用使用切換變量:

handleClick(){ 
    this.setState({fadeAway} => ({ 
    fadeAway: ! fadeAway 
)}; 
} 
... 
<Child 
    text={obj} 
    key={index} 
    onClick={() => this.handleClick} 
    className={this.state.fadeAway? 'class1' : 'class2'}/> 
+0

謝謝,但這種方法似乎切換類目標組件。我需要向點擊組件的同級中添加一個新類。 –

0

我perfer像currentWord使用狀態,以節省字中被點選父組件,presudo代碼如下所示:

class Parent extends Component { 
    constructor(){ 
    super(); 
    this.state = { 
     fadeAway: false, 
     currentWord: '' 
    }; 
    this.handleClick = this.handleClick.bind(this) 
    } 
    handleClick(currentWord){ 
    this.setState({ 
     currentWord: currentWord, 
    }); 
    } 
    render(){ 
    const array = ["Hello", "Hi", "How's it going", "Good Times"] 
    const currentWord = this.state.currentWord; 
    return(
     array.map(function(obj, index){ 
     <Child currentWord={currentWord} text={obj} key={index} onClick={() => this.handleClick} /> 
     }) 
    ) 
    } 
} 

,育兒組件

class Child extends Component { 
    // some other code 

    handleClick(e) { 
    this.props.handleClick(e.target.value); 
    } 

    render() { 
    const isSelected = this.props.text === this.props.currentWord; 
    // use isSelected to toggle className 

    <div 
     onClick={this.handleClick.bind(this)} 
    >{this.props.text} 
    </div> 
    } 
} 
+0

您將道具作爲'currentWord'傳遞,但在子組件中將其作爲'CurrentWord'引用。 – furkle

+0

錯字修正,謝謝。 – fung

1

我會在狀態簡單地存儲然後將fadeAway prop傳遞給子組件定義爲

fadeAway={this.state.selectedIndex !== index} 

之後,您只需根據this.prop.fadeAway在Child中設置fade-away類並定義必要的CSS規則。

這裏是如何可以看看你的情況:

class Parent extends React.Component{ 
 
    constructor() { 
 
    super(); 
 
    this.state = {selectedIndex: null} 
 
    } 
 
    handleClick (selectedIndex) { 
 
    this.setState({ selectedIndex }) 
 
    } 
 
    render() { 
 
    const array = ["Hello", "Hi", "How's it going", "Good Times"] 
 
    return (
 
     <div> 
 
     {array.map((obj, index) => { 
 
      const faded = this.state.selectedIndex && this.state.selectedIndex !== index 
 
      return <Child 
 
      text={obj} 
 
      fadeAway={faded} 
 
      key={index} 
 
      onClick={() => this.handleClick(index)} /> 
 
     })} 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
class Child extends React.Component { 
 
    render() { 
 
    return (
 
     <h2 
 
     onClick={this.props.onClick} 
 
     className={this.props.fadeAway ? 'fade-away' : ''}> 
 
     {this.props.text} 
 
     </h2> 
 
    ) 
 
    } 
 
} 
 

 
ReactDOM.render(
 
    <Parent />, 
 
    document.body 
 
);
.fade-away { 
 
    opacity: 0.3; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

+0

謝謝,這似乎很接近。但是,當頁面呈現時,我希望所有組件都具有完全不透明度。點擊時,其他人應該失去其不透明性。此解決方案將一個組件設置爲在頁面加載時處於活動狀態,此時它們應全部處於活動狀態,直到單擊該組件。有什麼建議? –

+0

@IanSpringer當然,只需使默認'selectedIndex'爲'null'並在'const faded = this.state.selectedIndex && this.state.selectedIndex!== index'中檢查它。檢查演示。 – dfsq