#javascript #reactjs #list #animation #mapping
#javascript #reactjs #Список #Анимация #сопоставление
Вопрос:
У меня есть веб-страница react, которая отображает список ссылок из массива, который находится внутри локальной базы данных. Я хочу показывать подсказки по ссылкам при наведении курсора мыши на каждую ссылку (элемент списка).
В настоящее время, когда я навожу курсор на элемент списка (ссылку на моей веб-странице), отображаются все подсказки по ссылкам из других ссылок. Я хочу только тот, на который я навожу курсор, чтобы показать подсказку. Как я могу добиться этого эффекта?
—
Проблема в действии:
—
Код реакции:
function Works() {
const [hoverHint, setHoverHint] = useState(false);
function showHoverHint() {
setHoverHint(true);
}
function hideHoverHint() {
setHoverHint(false);
}
const linkMaps = {
website: <Globe fill="#aaa" size={20} />,
github: <GitHub fill="#aaa" size={20} />,
gitlab: <GitLab fill="#aaa" size={20} />,
apk: <Android fill="#aaa" size={20} />,
youtube: <YouTube fill="#aaa" size={20} />
};
return(
<ul className="work-links">
{work.links.map(link => (
<li>
<span
className={
hoverHint ? 'before show-hint' : 'before hide-hint'
}
>
{link.text}
</span>
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
onMouseOver={showHoverHint}
onMouseOut={hideHoverHint}
>
{linkMaps[link.type]}
</a>
<span
className={
hoverHint ? 'after show-hint' : 'after hide-hint'
}
>
{link.text}
</span>
</li>
))}
</ul>
);
}
Код CSS:
.work-links {
list-style-type: none;
padding: 0;
margin-top: 0.3em;
margin-bottom: 0;
position: absolute;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
.work-links svg {
transition: 0.15s;
}
.work-links a {
display: inline-block;
padding: 0.4em 0.4em 0;
margin-bottom: 0.8em;
background-color: #eee;
border-radius: 50%;
transition: 0.15s;
z-index: 1;
}
.work-links a:hover {
background-color: #333;
}
.work-links a:hover svg {
fill: #eee;
}
.work-card-container:nth-child(odd) .work-links {
right: -11em;
align-items: flex-start;
}
.work-card-container:nth-child(even) .work-links {
left: -11em;
align-items: flex-end;
}
.work-card-container:nth-child(odd) .before {
display: none;
}
.work-card-container:nth-child(even) .before {
right: 0.5em;
transition: 0.1s;
}
.work-card-container:nth-child(even) .after {
display: none;
}
.work-card-container:nth-child(odd) .after {
left: 0.5em;
transition: 0.2s;
}
.hide-hint {
opacity: 0;
}
.work-card-container:nth-child(even) .hide-hint {
transform: translateX(50%);
}
.work-card-container:nth-child(odd) .hide-hint {
transform: translateX(-50%);
}
.show-hint {
transform: translateX(0);
opacity: 1;
}
.work-links > li {
display: flex;
align-items: center;
}
.work-links span {
position: relative;
top: -0.5em;
color: #888;
}
Ответ №1:
Вам нужно будет инициировать состояние наведения на основе уникального идентификатора, а не общего значения состояния.
Вот один подход, который приходит на ум:
const [selectedLink, setSelectedLink] = React.useState(null)
<ul className="work-links">
{work.links.map(link => (
<li>
<span
className={
hoverHint ? 'before show-hint' : 'before hide-hint'
}
>
{link.text}
</span>
<a
href={link.url}
target="_blank"
rel="noopener noreferrer"
// Use the URL as a unique identifier
onMouseOver={() => setSelectedLink(link.url)}
// Set to null on mouseout
onMouseOut={() => setSelectedLink(null)}
>
{linkMaps[link.type]}
</a>
<span
className={
selectedLink === link.url ? 'after show-hint' : 'after hide-hint'
}
>
{link.text}
</span>
</li>
))}
</ul>
Комментарии:
1. Спасибо за ваш быстрый ответ. Я обновил свой вопрос и добавил инструкции перед ‘return’ в моей функции react для справки. Что касается вашего ответа, как мне тогда использовать ‘link. url’ который находится внутри состояния ‘selectedLink’ для добавления / удаления классов ‘показать подсказку’ или ‘скрыть подсказку’?
2. Упс! Обновил мой ответ, ха-ха. Да, вы хотите сравнить
selectedLink
с повторяемымlink.url
свойством для запуска классов.