反应 - 切换 css class
React - toggle css class
我希望能够在列表的单个项目上切换 class "active" on/off。假设我们有一个元素列表:
<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>
我希望能够在点击时在第二个元素上添加 class "active"。我不能为此使用状态,因为它会改变其他 2 个元素的 classes,如果我们在那里添加条件,对吗?
所以解决方案可能是创建一个子组件,比如 <ListItem />
,它可以有自己的状态和自己的 onclick 方法,这只会改变他自己的 class。但是,当我们想要在点击时删除其他元素上的 class "active" 时,该子组件必须将方法分派给父级以从其他元素中删除 class 。对于一个简单的任务来说似乎相当复杂(你知道 10secs-in-jquery 那种)。
有人对此有更简单的解决方案吗?
如果不必为此使用另一个大的 npm 模块,document.getElementsByClassName(显然)和 refs,那就太好了。
解决此问题的正确方法是使用一个状态变量来定义当前 "active",即
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
设置为当前所选元素的 index/ref 即可。
您可以在 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>
我希望能够在列表的单个项目上切换 class "active" on/off。假设我们有一个元素列表:
<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>
我希望能够在点击时在第二个元素上添加 class "active"。我不能为此使用状态,因为它会改变其他 2 个元素的 classes,如果我们在那里添加条件,对吗?
所以解决方案可能是创建一个子组件,比如 <ListItem />
,它可以有自己的状态和自己的 onclick 方法,这只会改变他自己的 class。但是,当我们想要在点击时删除其他元素上的 class "active" 时,该子组件必须将方法分派给父级以从其他元素中删除 class 。对于一个简单的任务来说似乎相当复杂(你知道 10secs-in-jquery 那种)。
有人对此有更简单的解决方案吗?
如果不必为此使用另一个大的 npm 模块,document.getElementsByClassName(显然)和 refs,那就太好了。
解决此问题的正确方法是使用一个状态变量来定义当前 "active",即
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
设置为当前所选元素的 index/ref 即可。
您可以在 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>