CSS를 사용하여 조건부 렌더링하기

비얌·2023년 11월 14일
0
post-thumbnail

🧹 개요

리액트로 프로젝트를 하다가, 상위 컴포넌트가 hover될 때 하위 컴포넌트를 조건부 렌더링하고 싶었다.

처음에는 JavaScript로 hover될 때와 아닐 때를 state로 만들어 조건부 렌더링을 했다!

하지만 같은 기능을 JavaScript를 쓰지 않고 CSS만으로 구현하는 법을 알게 되어 기록으로 남겨보려고 한다.



✨ 결과 미리보기

아래 GIF의 각 상자는 Item이라는 컴포넌트이다. 이 Item 컴포넌트는 Container 안에 ActionButtons와 Status 컴포넌트로 이루어져 있다.

Container가 hover되면 ActionButtons가 렌더링되고, hover되지 않은 평소에는 Status가 렌더링되게 하려고 한다.

// Container가 hover되지 않았을 때(평소에)
Item
 ┗ Container
   ┣ ❌ActionButtons(안보임)⭕Status(보임)
   

// Container가 hover되었을 때
Item
 ┗ Container
   ┣ ⭕ActionButtons(보임)❌Status(안보임)



🛫 방법 1, 2

1. JavaScript로 hover시에 조건부 렌더링 구현

처음에는 JavaScript로 조건부 렌더링을 구현하려고 했다.

isHovered라는 state를 만들고 Container 컴포넌트가 hover되면(onMouseEnter) isHovered를 true로 만들고, 아니면(onMouseLeave) isHovered를 false로 만들었다.

그리고 isHovered가 true이면 ActionButtons를 렌더링하고, false이면 Status를 렌더링했다.

const Item = () => {
  const [isHovered, setIsHovered] = useState(false);

  return (
    <Container
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
    >
      {isHovered ? <ActionButtons /> : <Status>{status}</Status>}
    </Container>
  );
};

2. CSS로 hover시에 조건부 렌더링 구현

하지만 state를 만들지 않고 CSS만으로도 조건부 렌더링을 구현할 수 있었다.

  1. ActionButtons의 display를 none으로 설정하여 평소에는 안보이게 하기
  2. Container가 hover되면 ActionButtons의 display를 flex로 설정하여 보이게 하기(ActionButtons의 display가 기존에 flex였으므로)
  3. Container가 hover되면 Status의 display를 none으로 설정하여 안보이게 하기
const Item = () => {
  return (
    <Container>
      <ActionButtons className="hover-visible" />
      <Status className="hover-hidden">{status}</Status>
    </Container>
  );
};

const Container = styled.div`
  .hover-visible {
    display: none;
  }

  &:hover {
    .hover-hidden {
      display: none;
    }

    .hover-visible {
      display: flex;
    }
  }
`;


✨ 결과

Container가 hover되면 ActionButtons 컴포넌트가 나타나고, 평소에는(hover되지 않았을 때)에는 Status 컴포넌트가 렌더링된다!



🐹 회고

이런 문제는 CSS만으로는 해결하지 못할 줄 알았다. 그래서 지금까지 오직 CSS 효과만을 위해 JavaScript로 state를 만들어왔다. 그래서 새롭게 알게 된 방법을 꼭 기록해두고 싶었다.

다음에는 CSS로 해결할 수 있는 문제는 CSS로 해결했으면 좋겠다😆

profile
🐹강화하고 싶은 기억을 기록하고 공유하자🐹

0개의 댓글