我有一个通过在react上使用数组创建的元素列表。在用户单击时如何使被点击的元素处于活动状态(通过添加css类),同时使其他元素成为inative(通过删除活动类)?
我对elemetns的渲染看起来像这样。
{this.props.people.map(function(person, i){
<div className='media' key={i} onClick={state.handleClick.bind(state,i,state.props)}>
<item className="media-body">{person.name}</item>
</div>
}
用户点击其中一个元素后,活动的课程将被添加到点击的媒体中。使点击的元素“媒体活跃”的元素同时删除“活跃”&#39;来自先前点击的元素的类??
答案 0 :(得分:9)
constructor(props) {
super(props);
this.state = { activeIndex: 0 };
}
handleClick(index, props) {
// do something with props
// ...
// now update activeIndex
this.setState({ activeIndex: index });
}
render() {
return (
<div>
{
this.props.people.map(function(person, index) {
const className = this.state.activeIndex === index ? 'media active' : 'media';
return (
<div className={className} key={index} onClick={handleClick.bind(this, index, this.props)}>
<item className="media-body">{person.name}</item>
</div>
);
}, this)
}
</div>
);
}
答案 1 :(得分:0)
在 handleClick 方法中,您可以将所点击的人员存储在组件的状态中(看起来像是人物的集合)。然后根据个人的ID有条件地设置 className 。
您可以使用以下内容设置className:
className={this.state.clickedPersonId === i ? 'media media--clicked' : 'media'}
(NB这是使用 i ,人数组中项目的索引;您可能希望使用更明确的内容,例如人物&#39 ;真实的身份。)
答案 2 :(得分:0)
为了清洁代码,我个人建议您创建子组件以向映射元素添加功能。
您可以创建一个小的子组件,它只返回您想要添加功能的元素,如下所示:
...
this.state = {
active: false
}
...
return(
<div className=`media ${this.state.active ? 'active' : ''` onClick={()=>{this.setState({active: true})}}>
<item className="media-body">{this.props.name}</item>
</div>
)
...
在地图功能中,您只需将内容作为属性传递:
{this.props.people.map(function(person, i){
<SubComponent key={i} {...person} />
}
这样你就可以在“root”组件中使用干净的代码,并且可以增加子组件的复杂性。