본문 바로가기
🍀오늘도 삽질 중🍀/React.js

hover 시 이미지 및 글자 색 바뀌도록 구현하기

by 매진2 2023. 8. 9.
728x90

우리 사이트에서 유일한 재사용 컴포넌트가 아래에 적어내려갈 상품 미리보기 컴포넌트이다.

메인과 상품 리스트 그리고 상품 상세페이지에 들어갈 컴포넌트이기 때문에미리 분리 작업을 했었다.

그리고 제일 먼저 작업을 해 main으로 merge해 이후 작업에서 바로 쓸 수 있도록 활용했다.

 

처음 시작을 할때엔 hover 시 이미지가 바뀌는 것이니까 css의 hover 속성을 이용해서 해보려고 했으나

바뀌어야하는 이미지가 db에서 받아와야하는 데이터라서 할 수 없었다.

 

다른 방법을 찾은 결과 event 중 mouseOver 와 mouseOut이 있었다.

그래서 이번엔 event를 사용해 이미지를 바꿔주는 작업을 해보려고 한다.

만약 styled-components를 사용한다면 js 파일에 css를 적을 수 있기때문에 event를 사용하지 않아도 된다.

 

useState와 event 적용하기

useState를 boolean으로 isHover를 관리하려고 했다.

true가 되었을 땐 hover 했을 때의 이미지를 노출하고 false가 되었을 땐 기본이미지를 노출 하려고 했다.

useState를 사용하면 전체가 리랜더링이 되어서 왠만하면 사용하고 싶지 않았는데 다른 방법을 못 찾았다.

 

여러 event 중 mouseOver와 mouseOut을 사용했고 리액트로 구현했기때문에 앞에 on을 붙여주었다.

이때 modal 구현처럼 setIsHover(!isHover)로 구현을 했더니 버벅거림이 있었다.

왜그럴까 하고 한참을 고민했는데 간단하게 생각해보니 over를 했을 땐 무조건 true이고 out을 했을 땐 무조건 false라는 사실을 발견했다.

  const [isHover, setIsHover] = useState(false);

      onMouseOver={() => {
        setIsHover(true);
      }}
      
      onMouseOut={() => {
        setIsHover(false);
      }}

 

div와 img 태그에 useState와 event 적용하기

이미 useState와 event를 만들어뒀기 때문에 이후의 과정들은 아주 쉽다.

먼저 div 태그 상위에 만들어둔 event를 적용한다.

 <div
      onMouseOver={() => {
        setIsHover(true);
      }}
      onMouseOut={() => {
        setIsHover(false);
      }}
    >
 </div>

그리고 img 태그에도 isHover가 true 일때 hover했을 때 노출하고 싶은 이미지를,

false일 땐 기본 이미지로 노출이 되도록 삼항연산자로 구현해주었다.

이 때 width와 height는 부모에게 props로 받아오는 값이며 값이 있다면 props 값으로, 없다면 300이 되도록 구현했다.

main과 리스트 페이지에서는 300으로 사용하고 있지만 상품상페 페이지에서는 200으로 줄여서 사용하고 싶었기때문이다.

          <img
              className="itemImg"
              style={{
                width: width ? width : 300,
                height: height ? height : 300,
              }}
              src={isHover ? productHoverImage : productThumbnailImage}
              alt="itemImg"
            />

 

다음에는 styled-components로

이번에는 배운게 css, scss 뿐이라 어쩔 수 없이 event를 사용했다. 하지만 다음에 hover로 image를 변경해야하는 상황이 온다면 state를 줄여 랜더링 횟수를 줄일 수 있도록 styled-components랑 scss를 같이 써보고 싶다. 사실 요즘 인턴으로 일하면서 module, 부트스트랩 등을 알게되어서 새로 알게된 것들과 styled-components를 mix해 사용해보고싶다.

728x90