Есть ли способ, чтобы функция карты выполняла раскрывающееся меню только для одной корзины. Сейчас, если я нажму на один значок меню, каждое раскрывающееся меню появится для каждой карты на карте.
const [isOpen, setIsOpen] = useState(false);
{albums.map((album, i) => (
<Card width = "23rem" height = "16rem" bckImg = {album.bckImgUrl} key = {i}>
<AlbumtTitle color = {album.color}>{album.name}</AlbumtTitle>
<LinkButton background = {album.color} to = {`/albums/${album._id}`}>
See more
</LinkButton>
<KebabMenu onClick = {() => setIsOpen(!isOpen)} open = {isOpen}>
{isOpen ? (
<Dropdown
ref = {ref}
style = {{
width: "50px",
height: "50px",
}}
>
<li>
<Link to = {`editAlbum/${album._id}`}>Edit</Link>
</li>
<hr />
<li>Delete</li>
</Dropdown>
) : (
<Dots />
)}
</KebabMenu>
</Card>
))}
Как хранить отдельно?
Ваше состояние isOpen может быть объектом, который отслеживает открытое состояние для каждого элемента в альбоме:
const [isOpen, setIsOpen] = useState({});
{albums.map((album, i) => (
<Card width = "23rem" height = "16rem" bckImg = {album.bckImgUrl} key = {i}>
<AlbumtTitle color = {album.color}>{album.name}</AlbumtTitle>
<LinkButton background = {album.color} to = {`/albums/${album._id}`}>
See more
</LinkButton>
<KebabMenu
onClick = {() =>
setIsOpen({ ...isOpen, [album._id]: !isOpen[album._id] })
}
open = {!!isOpen[album._id]}
>
{isOpen[album._id] ? (
<Dropdown
ref = {ref}
style = {{
width: "50px",
height: "50px",
}}
>
<li>
<Link to = {`editAlbum/${album._id}`}>Edit</Link>
</li>
<hr />
<li>Delete</li>
</Dropdown>
) : (
<Dots />
)}
</KebabMenu>
</Card>
))}
Хорошо ли, что я изменил вашу константу [isOpen, setIsOpen] = useState ({}); в const [isOpen, setIsOpen] = useState(false);. Я сделал это, потому что он устанавливает состояние при втором щелчке, не замечая этого.
Это не сработает; это должен быть объект, потому что для каждого Album_id должно быть логическое значение.
@KubaKluzniak это будет работать и игнорировать значение по умолчанию, но это не очень хорошая практика, просто поставьте {} вместо логического значения в качестве начального значения
Хорошо. i Измените его на это: useState({ id: undefined, state: false }); setIsOpen({ [album._id]: !isOpen[album._id] })} и все работает нормально
Не уверен, почему вы пытаетесь установить такое состояние по умолчанию. Это все еще не репрезентативно того, как это будет выглядеть. В конечном итоге состояние будет выглядеть как {1: true, 2: false, 3: false} и т. д. (при условии, что идентификаторы альбомов равны 1, 2 и 3).
@Nick, потому что при первом щелчке в раскрывающемся списке, когда sate является пустым объектом, сначала ничего не происходит, он начинает работать при втором щелчке.
Вместо
{albums.map((album, i) => (...your code...))}
Нужно проверить, есть ли у вас хоть один элемент в альбомах, и если да, то обработать его:
{if (albums.length > 0) {
return albums.slice(0,1).map((album, i) => (...your code...))
} else {
return null // or any other actions you want to take in case there are no albums
}
}
Для уточнения проверяем длину альбомов, если она не пустая. Если это так, мы берем только первый элемент и обрабатываем его.
Спасибо за предложение, я добавлю это.
@kuba-kluzniak, пожалуйста, проголосуйте за мой ответ, если он вам помог :)
Вы должны хранить состояние isOpen для каждого раскрывающегося списка отдельно. В настоящее время одно состояние isOpen управляет всеми выпадающими списками одновременно.