Показывать наведение на определенную карту в react

#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, чтобы разделить их.