#javascript #reactjs #hover
#javascript #reactjs #наведение
Вопрос:
Я сталкиваюсь с этой проблемой. Я хочу показать поле наведения курсора на это выбранное поле. Например, когда я наведу курсор на поле Один, я хочу показать наведение курсора Один, поле Два -> Наведение курсора два. Но в моем примере, когда я навожу курсор на одну, отображаются оба. Я пытаюсь сделать это с помощью ссылок или e.target, но всегда что-то не так, как я хочу. Ссылка на stackblitz: https://stackblitz.com/edit/react-hc4741?file=src/App.js
import React, { useState } from "react";
import "./style.css";
import { BooksSection, BookCard, BookCardHover } from "./Styled";
export default function App() {
const [displayBookCardHover, setDisplayBookCardHover] = useState(false);
const showCardHover = () => {
setDisplayBookCardHover(true);
};
const hiddenCardHover = () => {
setDisplayBookCardHover(false);
};
return (
<div>
<BooksSection>
<BookCard
bgColor={"#000"}
color={"#fff"}
onMouseEnter={showCardHover}
onMouseLeave={hiddenCardHover}
>
<BookCardHover display={displayBookCardHover}>
Hover One
</BookCardHover>
Box One
</BookCard>
<BookCard
bgColor={"#fff"}
color={"#000"}
onMouseEnter={showCardHover}
onMouseLeave={hiddenCardHover}
>
<BookCardHover display={displayBookCardHover}>
Hover Two
</BookCardHover>
Box Two
</BookCard>
</BooksSection>
</div>
);
}
стилизованные компоненты
import styled from "styled-components";
export const BooksSection = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 100wh;
`;
export const BookCard = styled.div`
width: 50%;
height: 500px;
padding: 20px 0;
background: ${props => props.bgColor};
color: ${props => props.color};
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
`;
export const BookCardHover = styled.div`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
font-size: 50px;
background: rgba(0, 0, 0, 0.7);
visibility: ${({ display }) => (display ? "100" : "hidden")};
`;
Ответ №1:
Проблема в том, что у вас есть один и тот же компонент с одинаковым значением prop в обоих местах, поэтому они будут отображаться / скрыты одновременно, независимо от того, что вы делаете со displayBookCardHover
значением.
Хитрость заключается в том, чтобы использовать отдельное значение для каждого. Вот так:
const [hoverIndex, setHoverIndex] = useState(-1);
...
const showCardHover = (index) => {
setHoverIndex(index);
}
const hiddenCardHover = () => {
setHoverIndex(-1);
}
...
<BookCard
...
onMouseEnter={() => showCardHover(0)}
...
>
<BookCardHover display={hoverIndex === 0}>
...
<BookCardHover display={hoverIndex === 1}>
Надеюсь, вы поняли идею.
Кстати, для prop нет значения «100» visibility
. Он либо «скрыт», либо «виден».
Комментарии:
1. Обновил ответ, если вам все еще интересно, как это сделать.
Ответ №2:
import React, { useState } from "react";
import "./style.css";
import { BooksSection, BookCard, BookCardHover } from "./Styled";
export default function App() {
const [displayBookCardHover, setDisplayBookCardHover] = useState({
boxOneHover: false,
boxTowHover: false
});
const showCardHover = box => {
if (box === 1) {
setDisplayBookCardHover(ps=>({ ...ps, boxOneHover: true }));
} else {
setDisplayBookCardHover(ps=>({ ...ps, boxTowHover: true }));
}
};
const hiddenCardHover = box => {
if (box === 1) {
setDisplayBookCardHover(ps=>({ ...ps, boxOneHover: false }));
} else {
setDisplayBookCardHover(ps=>({ ...ps, boxTowHover: false }));
}
};
return (
<div>
<BooksSection>
<BookCard
bgColor={"#000"}
color={"#fff"}
onMouseEnter={() => showCardHover(1)}
onMouseLeave={() => hiddenCardHover(1)}
>
<BookCardHover display={displayBookCardHover.boxOneHover}>
Hover One
</BookCardHover>
Box One
</BookCard>
<BookCard
bgColor={"#fff"}
color={"#000"}
onMouseEnter={() => showCardHover(2)}
onMouseLeave={() => hiddenCardHover(2)}
>
<BookCardHover display={displayBookCardHover.boxTowHover}>
Hover Two
</BookCardHover>
Box Two
</BookCard>
</BooksSection>
</div>
);
}
Ответ №3:
Я думаю, что BookCard должен быть компонентом. У каждого должно быть свое собственное состояние. В App.js вы можете использовать BookCard и передать bgColor и color и все, что вы хотите, чтобы настроить каждую BookCard в качестве реквизита и использовать их в нем.
Ответ №4:
Проблема с вашим кодом заключается в том, что оба BookCardHover
компонента основывают свое состояние отображения, используя одно и то же ссылочное состояние displayBookCardHover
, поэтому, когда одно из них изменяет значение displayBookCardHover
, оно автоматически отражается на другом. Я бы рекомендовал подход, предложенный @technophyle, чтобы разделить их.