Ayden's journal

리액트와 CSS, 그리고 애니메이션

리액트

프론트엔드 개발자로 면접을 보다보면 '왜 vue나 angular가 아니라 react를 주력으로 사용하는지' 물어보는 면접관들이 이따금씩 존재한다. 나는 아주 솔직한 사람이기 때문에 대부분의 경우 '회사에서 보통 react를 가장 많이 사용하고 있기 때문'이라고 답한다. 그렇지만 이 대답만으로 끝나지는 않는다. 나는 몇 가지 부연설명을 곁들인다.

vue는 3 버전 이후로 react와 크게 다를 바 없어졌다고 생각한다. anguler는 일반적인 수준의 프로젝트의 경우 그 복잡도로 인해서 react를 대신할 메리트가 없다고 느껴진다. svelte까지 포함해서 세 개의 라이브러리(혹은 프레임워크)는 모두 데이터가 양방향으로 바인딩되거나, 양방향 데이터 바인딩을 지원한다. react부터 시작한 사람이라 그런가 데이터 바인딩이 양방향이면 어쩐지 조금 불안하게 느껴진다. 내가 flux 패턴의 신봉자까지는 아니지만, 데이터의 출처나 데이터 흐름의 복잡성을 해결해준다는 측면에서 단방향 데이터 바인딩을 조금 더 선호하게 되는 듯하다.

 

CSS

리액트에서 CSS를 사용하는 방법은 크게 css-in-css와 css-in-js 두 가지로 나뉜다. 전자의 경우 표준 css를 그대로 넣거나 moduleCSS를 사용하는 방법이 있고, 후자의 경우에는 Emotion∙StyledComponent∙TailwindCSS∙StyleX 등이 있겠다. 내 취향이 무엇이냐고 묻는다면 단연 moduleCSS이지만 실제로 더 많이 사용하고 있는 것은 TailwindCSS이다. 최근 StyleX에 관심이 생기고 있기는 하지만 앞으로 꽤 오랫동안은 TailwindCSS랑 친하게 지낼 것 같다.

이유는 간단한데, SSR 환경에서 불안정한 CSS-in-JS 방식을 제외하고 남는 CSS 솔루션 중에서 Tailwind CSS가 가장 CSS의 단점을 잘 커버할 수 있기 때문이다. 단점이라면 너저분하게 늘어나는 클래스들을 바라보고 있으면 속이 답답해진다는 것 정도일까?

 

애니메이션

css에 딸려있는 animation 프로퍼티를 말하려는 건 아니다. 오히려 transition 프로퍼티에 대해 말하게 될 것이다. 최근에 개인 프로젝트를 하면서 사이드바를 하나 만들어야 했다. 요구 사항은 다음과 같았다. "평소에는 보이지 않다가, 네비게이션 바에 있는 햄버거 버튼을 누르면 왼쪽에서 스르르 밀려나오는 사이드바." 이를 위해서 전역 상태 하나가 필요했고, tailwindCSS를 사용해서 transition 하는 방법을 알아야 했다.

처음에는 Zustand를 사용해 전역 상태를 관리했었다. 그런데 도중에 공부하다가 나만의 전역 상태 관리 도구 caro-kann을 만들어버렸고, 일단 만들었으니 써먹어야할 거 같아 이를 사용하기로 했다.

// useSideBarBoard.tsx
export const useSideBarBoard = playTartakower<boolean>(false)

 

그리고 SideMenu 컴포넌트는 아래와 같이 만들었다. isSideBarOpen의 불린 값을 통해 선택적으로 tailwindCSS 클래스를 적용할 수 있게 했다.

const SideMenu = () => {
  const [ isSideBarOpen, setIsSideBarOpen ] = useSideBarBoard();

  return (
    <aside
      className={`${isSideBarOpen ? "ml-0" : "-ml-[100%] desk:-ml-0"}
      w-full desk:h-[100dvh] tab:w-250 transition-all ease-in-out fixed desk:static top-0 left-0 bottom-0 right-0`}
    >
      <IoCloseSharp onClick={setIsSideBarOpen((prev) => !prev)} />
    </aside>
  );
};

export default SideMenu;

여기서 중요한 부분은 transition-all, ease-in-out 클래스라고 생각한다. transition-all은 어떤 프로퍼티의 값이 변경되었을 때, 이를 부드럽게 보일 수 있도록 transition 시키는 역할을 한다. ease-in-out는 프로퍼티의 값이 a에서 b로 변경되었을 때, transition 시간동안 가속을 어떻게 처리할 것인지를 정의하는 역할을 한다. 

 

transition과 transform을 잘 버무리면 재미있는 애니메이션을 만들 수 있을 것 같다는 게 오늘 잡생각의 결론이지 싶다.

블로그의 정보

Ayden's journal

Beard Weard Ayden

활동하기