Emotion🤔
Emotion은 리액트에서 스타일을 관리하기 위한 CSS-in-JS 라이브러리로, 자바스크립트 코드 내에서 직접 CSS를 작성하고 적용할 수 있게 해 줍니다. Emotion 외에도 Styled-Components가 주로 사용됩니다.
Styled-Components 대신 Emotion을 선택한 이유🤔
Emotion을 선택한 첫 번째 이유는 styled-components는 이전 미션과 프로젝트를 통해 많이 경험해봤기 때문에 새로운 라이브러리를 경험해 보고 싶어서입니다. 트렌드를 따라가는 것도 좋지만 여러 라이브러리를 사용해 보면 왜 특정 라이브러리가 많이 사용되는지 비교해 볼 수 있을 것 같습니다😊
두 번째 이유는 자주 참조하는 toss에서 Emotion을 주 기술로 사용하고 있다는 점입니다. Emotion을 활용해봄으로써 실제 기업에서 사용되는 기술을 배우고, 그 효율성이나 장점들을 직접 경험할 수 있는 좋은 기회라고 생각했습니다.
위 내용은 개인적인 이유이니, Emotion을 사용했을 때 장점도 알아봐야겠죠❓
💡Emotion의 장점
- 동적 스타일링 지원 : 컴포넌트의 props나 state에 따라 스타일을 동적으로 변경할 수 있어, 다양한 상태에 따른 스타일링이 가능합니다.
- 서버 사이드 렌더링(SSR) 지원 : Emotion은 Next.js와 같은 서버 사이드 렌더링 환경에서 별도의 설정 없이 동작해 SSR을 구현할 때 편리합니다.
- 작은 번들 크기 : Emotion은 Styled-Components에 비해 번들 크기가 작아, 애플리케이션의 로딩 속도를 향상시킬 수 있습니다.
이제 프로젝트에 emotion을 적용해 보겠습니다❗
✨Emotion 설치 및 import
npm install @emotion/react @emotion/styled
설치가 완료되면 아래와 같이 import 해서 사용할 수 있습니다.
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import 까지 끝났으니 이제 emotion/react와 emotion/styled를 사용하는 방법을 각각 예시로 확인해 보겠습니다👀
@emotion/react 사용 예제
@emotion/react를 사용하여 스타일을 정의하고 css prop을 사용하여 리액트 컴포넌트에 적용하는 방식입니다.
toss github을 확인해보니 이 방법을 채택했네요❗
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';
function App() {
return (
<div
css={css`
background-color: #000000;
padding: 20px;
border-radius: 8px;
`}
>
<h1
css={css`
color: #ffffff;
font-size: 30px;
font-weight: bold;
`}>
Emotion React!
</h1>
</div>
);
}
export default App;
- /** @jsxImportSource @emotion/react */ 는 jsx 파일이 css prop을 읽을 수 있게 하기 위해 선언합니다.
- css prop을 사용하여 인라인으로 스타일을 정의하고 HTML 요소에 바로 적용합니다.
- 각 요소마다 css prop을 사용해 스타일을 개별적으로 지정할 수 있습니다.
@emotion/styled 사용 예제
@emotion/styled는 styled-components와 비슷한 방식으로 리액트 컴포넌트를 스타일링할 수 있게 해주는 API입니다. styled 함수는 스타일링 된 컴포넌트를 반환하고, 이 컴포넌트를 JSX에서 사용할 수 있습니다. 이는 리액트의 컴포넌트와 스타일을 결합하는 선언적인 방식입니다.
import styled from '@emotion/styled';
const Wrapper = styled.div`
background-color: lightblue;
padding: 20px;
border-radius: 8px;
`;
const Title = styled.h1`
color: #ffffff;
font-size: 30px;
font-weight: bold;
`;
function App() {
return (
<Wrapper>
<Title>Emotion Styled!</Title>
</Wrapper>
);
}
export default App;
- styled.div와 styled.h1을 사용하여 스타일링된 Wrapper와 Title 컴포넌트를 생성합니다.
- styled를 사용하면 해당 컴포넌트를 재사용 가능하고 선언적으로 스타일링할 수 있습니다.
두 방법 모두 동적 스타일링이 가능하고, 애플리케이션의 요구사항에 맞는 스타일링 방식을 선택하시면 될 것 같네요😊
저는 Styled-Components와 유사한 점과 스타일링된 컴포넌트를 생성하고 여러 곳에서 재사용할 수 있다는 점에서 @emotion/styled 방식을 선택했습니다❗
프로젝트에 적용해 보니 컴포넌트를 재사용할 수 있고 동적으로 스타일링 할 수 있다는 점에서 너무 만족스러웠어요.
@emotion/styled 예시: 동적 스타일링
import styled from '@emotion/styled';
import { useState } from 'react';
// styled-components로 테마에 따라 스타일 변경
const Container = styled.div<{ darkMode: boolean }>`
background-color: ${(props) => (props.darkMode ? '#000' : '#fff')};
color: ${(props) => (props.darkMode ? '#fff' : '#000')};
padding: 20px;
border-radius: 8px;
transition: background-color 0.3s, color 0.3s;
`;
const Button = styled.button`
background-color: blue;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
border-radius: 4px;
&:hover {
background-color: green;
}
`;
function App() {
const [darkMode, setDarkMode] = useState(false);
return (
<Container darkMode={darkMode}>
<h1>{darkMode ? 'Dark Mode' : 'Light Mode'}</h1>
<Button onClick={() => setDarkMode(!darkMode)}>Toggle Theme</Button>
</Container>
);
}
export default App;
- Container는 darkMode prop을 사용하여 스타일을 동적으로 변경합니다. darkMode가 true일 때 검정 배경색을, false일 때 하얀 배경색을 적용합니다.
- Button 컴포넌트는 클릭 시 darkMode 상태를 토글하여, 전체 UI의 테마를 변경합니다.
@emotion/styled 예시: 재사용 가능한 컴포넌트
import styled from '@emotion/styled';
// 스타일링된 Button 컴포넌트 생성
const Button = styled.button<{ primary?: boolean }>`
background-color: ${(props) => (props.primary ? 'blue' : 'gray')};
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
&:hover {
background-color: ${(props) => (props.primary ? 'darkblue' : 'darkgray')};
}
`;
function App() {
return (
<div>
<Button primary>Primary Button</Button>
<Button>Secondary Button</Button>
</div>
);
}
export default App;
- Button 컴포넌트는 styled.button을 사용하여 버튼 스타일을 정의합니다.
- primary prop을 통해 버튼의 배경색을 동적으로 변경할 수 있습니다.
- primary prop이 true이면 파란색 배경, false이면 회색 배경이 적용됩니다.
- @emotion/styled를 사용하여 컴포넌트를 정의하고, 이 컴포넌트를 여러 곳에서 재사용할 수 있습니다.
Emotion을 사용해보고 느낀 점📕
Emotion을 사용해 보면서 단점을 딱히 느끼지 못했습니다. 오히려 좋은 점이 훨씬 많았는데요, 간단하게 정리해 보겠습니다.
- props와 state를 이용한 동적 스타일링이 가능해 편리하다.
- scss 문법을 사용할 수 있어 편리하다.
- scss 문법에 js 함수, 조건문을 활용할 수 있어 편리하다.
- 전역 스타일링과 테마 관리 기능을 제공해 다크 모드나 사용자 정의 스타일을 구현하는데 편리하다.
Emotion을 어떻게 사용했는지 궁금하신 분들을 위해 아래 제 github의 Design-System 레포지토리를 남겨두겠습니다.
부족하지만 참고해 보시고, 피드백도 남겨주신다면 감사하겠습니다😊
'개발 공부 일지 > React' 카테고리의 다른 글
[React] 리액트 라이프사이클(Lifecycle)과 useEffect (6) | 2024.12.26 |
---|---|
[React] React Hook Form 라이브러리로 Form 간편하게 관리하기 (2) | 2024.11.27 |
[React] Compound Component Pattern (4) | 2024.11.15 |
[React] Render Props Pattern (2) | 2024.11.14 |
[React] IntersectionObserver를 통한 스크롤 이벤트 (0) | 2024.11.05 |