[英]React.js: How to change icon when item in the list is clicked?
I'm trying to implement a logic, where based on clicked item, arrow down
icon changes to arrow-up
and if user clicks 2nd time to the same row should again change.我正在尝试实现一个逻辑,根据单击的项目,
arrow down
图标更改为arrow-up
,如果用户第二次单击同一行应该再次更改。
I tried to trigger it based on the index of clicked item, but doesn't work properly.我试图根据点击项的索引来触发它,但不能正常工作。
Also tried to change the icons based on boolean state change like here还尝试根据布尔状态更改更改图标,如下所示
const handleClick = () => {
setOpen(!open);
};
But this approach changes state for all icons in the state.但是这种方法会改变状态中所有图标的状态。
Here is the code and sandbox link .这是代码和沙盒链接。
import React, { useState } from "react";
import { ListGroup } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleUp, faAngleDown } from "@fortawesome/free-solid-svg-icons";
export const defaultListData = [
{
name: "Dapibus ac facilisis in"
},
{
name: "Morbi leo risus"
},
{
name: "Porta ac consectetur ac"
},
{
name: "Porta ac doesfvsaard asdas"
}
];
function UserSettings() {
const [open, setOpen] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(0);
const handleClick = () => {
setOpen(!open);
};
function handleTests(index) {
setSelectedIndex(index);
}
return (
<div>
{defaultListData.map((category, i) => (
<ListGroup key={category.name} variant="flush">
<ListGroup.Item
onClick={(e) => handleTests(i)}
style={{ display: "flex", gap: "50px" }}
>
{category.name}
<FontAwesomeIcon
style={{ color: "green", cursor: "pointer" }}
icon={selectedIndex === i ? faAngleDown : faAngleUp}
/>
</ListGroup.Item>
</ListGroup>
))}
</div>
);
}
export default UserSettings;
Any help will be appreciated任何帮助将不胜感激
You need maintain state for each record check out below example您需要维护每条记录的状态,请查看以下示例
import React, { useState } from "react";
import { ListGroup } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleUp, faAngleDown } from "@fortawesome/free-solid-svg-icons";
function UserSettings() {
const [open, setOpen] = useState(false);
const [defaultListData, setDefaultListData] = useState([
{
name: "Dapibus ac facilisis in",
selected: false
},
{
name: "Morbi leo risus",
selected: false
},
{
name: "Porta ac consectetur ac",
selected: false
},
{
name: "Porta ac doesfvsaard asdas",
selected: false
}
]);
const handleClick = () => {
setOpen(!open);
};
function handleTests(index) {
let updateData = defaultListData.map((item, i) => {
return index === i ? { ...item, selected: !item.selected } : item;
});
setDefaultListData(updateData);
}
return (
<div>
{defaultListData.map((category, i) => (
<ListGroup key={category.name} variant="flush">
<ListGroup.Item
onClick={(e) => handleTests(i)}
style={{ display: "flex", gap: "50px" }}
>
{category.name}
<FontAwesomeIcon
style={{ color: "green", cursor: "pointer" }}
icon={category.selected ? faAngleDown : faAngleUp}
/>
</ListGroup.Item>
</ListGroup>
))}
</div>
);
}
export default UserSettings;
You want to toggle change the selectedIndex
depending on whether the clicked item is already open.您想根据单击的项目是否已打开来切换更改
selectedIndex
。 The better way would be to move the Item
to a separate component that has its own open
state:更好的方法是将
Item
移动到具有自己open
状态的单独组件:
const Item = (props) => {
const [open, setOpen] = useState(false);
const handleClick = () => {
setOpen((prev) => !prev);
};
return (
<ListGroup.Item
onClick={(e) => handleClick()}
style={{ display: "flex", gap: "50px" }}
>
{props.category.name}
<FontAwesomeIcon
style={{ color: "green", cursor: "pointer" }}
icon={open ? faAngleDown : faAngleUp}
/>
</ListGroup.Item>
);
};
function UserSettings() {
return (
<div>
{defaultListData.map((category, i) => (
<ListGroup key={category.name} variant="flush">
<Item category={category} />
</ListGroup>
))}
</div>
);
}
This is happening because your icon is being changed only when selectedIndex === i
what means that, only the row that you've clicked will be faAngleDown
.发生这种情况是因为您的图标仅在
selectedIndex === i
时才会更改,这意味着,只有您单击的行将是faAngleDown
。
In this case, a nice approach would be annother variable, like a flag, in the defaultListData
and check it to render the right icon.在这种情况下,一个不错的方法是在
defaultListData
中设置另一个变量,如标志,并检查它以呈现正确的图标。
Ex.:前任。:
export const defaultListData = [
{
name: "Dapibus ac facilisis in",
isOpen: false
},
{
name: "Morbi leo risus",
isOpen: false
},
{
name: "Porta ac consectetur ac",
isOpen: false
},
{
name: "Porta ac doesfvsaard asdas",
isOpen: false
}
];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.