[英]Add class to siblings when Component clicked in React
I'm working on building my portfolio using React.js. 我正在使用React.js构建我的投资组合。 In one section, I have four components laid out in a grid.
在一节中,我将四个组件布置在一个网格中。 What I want to do achieve is when one component is clicked, a css class is added to the siblings of this component so that their opacity is reduced and only the clicked component remains.
我要做的是单击一个组件时,将一个CSS类添加到该组件的同级中,以降低其不透明度,仅保留被单击的组件。 In jQuery, it would be something like $('.component').on('click', function(){ $(this).siblings.addClass('fadeAway')}).
在jQuery中,它类似于$('。component')。on('click',function(){$(this).siblings.addClass('fadeAway')})。 How can I achieve this effect?
我怎样才能达到这种效果? Here is my code, thanks in advance for any and all help!
这是我的代码,在此先感谢您提供的所有帮助!
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} />
})
)
}
}
A working example for this problem could look something like this, with a marginally more complex initialization array: 这个问题的可行示例可能看起来像这样,带有稍微复杂一些的初始化数组:
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} />
});
);
}
}
Then you would just add a ternary, like so, to the Child
component: 然后,您只需向
Child
组件添加一个三元,就像这样:
<Child
id={this.props.id}
className={this.props.reduced ? "reduced" : ""} />
This adds a bit more boilerplate than other examples, but it's extremely brittle to tie business logic to the text inside a component, and a stronger solution requires a stronger piece of identification, like an ID or class on the rendered DOM element. 与其他示例相比,这增加了一些样板,但是将业务逻辑绑定到组件内部的文本非常脆弱,并且更强大的解决方案需要更强大的标识,例如呈现的DOM元素上的ID或类。 This solution also, if you so wish, easily allows you to expand your logic so that more than one element can remain at maximum opacity at once.
如果您愿意的话,此解决方案还可以轻松地扩展您的逻辑,以使多个元素可以一次保持最大不透明度。
I would simply store in state index of selected item, and then pass fadeAway
prop into Child component defined as 我只是将其存储在所选项目的状态索引中,然后将
fadeAway
传递fadeAway
定义为
fadeAway={this.state.selectedIndex !== index}
After that you only need to set a fade-away
class in Child based on this.prop.fadeAway
and define necessary CSS rules. 之后,您仅需要基于
this.prop.fadeAway
在Child中设置一个fade-away
类,并定义必要的CSS规则。
Here is how it could look in your case: 这是您情况下的外观:
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>
You can achieve that using using a toggle variable : 您可以使用切换变量来实现:
handleClick(){
this.setState({fadeAway} => ({
fadeAway: ! fadeAway
)};
}
...
<Child
text={obj}
key={index}
onClick={() => this.handleClick}
className={this.state.fadeAway? 'class1' : 'class2'}/>
I perfer use state like currentWord
to save the word was clicked in Parent component, presudo code is like below: 我认为使用诸如
currentWord
类的currentWord
来保存在Parent组件中单击的单词,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} />
})
)
}
}
And in Child component 在子组件中
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>
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.