我希望能够在列表的单个项目上打开/关闭“活动”类。假设我们有一个元素列表:
<ul>
<li><a href="#" className="list-item">First</a></li>
<li><a href="#" className="list-item">Second</a></li>
<li><a href="#" className="list-item">Third</a></li>
</ul>
我希望能够在点击时在第二个元素上添加类“active”。我不能使用state,因为它会改变其他2个元素的类,如果我们在那里添加条件,对吧?
所以解决方案可能是创建一个子组件,说<ListItem />
,它可以有自己的状态和自己的onclick方法,只会改变自己的类。但是,当我们想要在click上删除其他元素上的“active”类时,这个子组件必须将方法分派给父类以从其他元素中删除类。对于一个简单的任务来说,这似乎很复杂(你知道10secs-in-jquery类)。
有没有人有更简单的解决方案?
没有必要使用另一个大的npm模块,document.getElementsByClassName(显然)也不是refs,这将是非常好的。
答案 0 :(得分:2)
解决这个问题的正确方法是使用一个状态变量来定义哪一个当前是“活动的”,即
this.state = {
active: "first" // (or "second", "third", null, etc..)
};
然后,您可以使用内联if语句,如下所示:
<li><a href="#" className={"list-item" + (this.state.active == "first" ? " active": "")}>First</a></li>
请注意,我假设您要对这些列表元素进行硬编码 - 如果这些元素是动态生成的,那么将this.state.active
设置为当前所选元素的索引/ ref是一件简单的事情。
答案 1 :(得分:2)
您可以在item
组件之外管理所选状态,并将其作为道具传递
onSelect
/ onClick
的事件处理程序可以触发并更改state
。
const data = [1,2,3,4,5];
class List extends React.Component {
constructor(props){
super(props);
this.state = {
selectedItem: 0
};
this.onSelect = this.onSelect.bind(this);
}
onSelect(id){
this.setState({
selectedItem: id
});
}
render() {
const {selectedItem} = this.state;
return (
<ul>
{data.map((d, index) => {
return <ListItem
key={index}
selected={index + 1 == selectedItem}
value={d}
id={d}
onSelect={this.onSelect}
/>
})}
</ul>
)
}
}
const ListItem = (props) => {
const onSelect = (e) => {
props.onSelect(e.target.id);
}
const className = props.selected && "selected";
return <li className={className} id={props.id} onClick={onSelect}>{props.value}</li>
}
ReactDOM.render(<List />, document.getElementById("root"));
ul{
list-style: none;
}
li{
padding: 5px;
border: 1px solid #ccc;
cursor: pointer;
}
li.selected{
background-color: green;
color: #fff;
}
<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>
<div id="root"></div>