[리액트] CSS in JS, Styled Components 란

2023. 4. 17. 13:59개발/React

CSS in JS

CSS 스타일을 JavaScript 코드 안에서 정의하고 관리하는 방식을 말한다!
CSS 클래스 이름이나 인라인 스타일을 직접 작성하는 대신, JavaScript 객체를 사용하여 스타일을 정의하고 관리할 수 있다.

  1. 컴포넌트별 스타일 관리 : 컴포넌트별로 스타일을 관리할 수 있다. 이를 통해 스타일의 재사용성을 높이고, 스타일 충돌 문제를 해결할 수 있다.
  2. JavaScript의 기능 활용 : JavaScript의 기능을 활용하여 동적으로 스타일을 변경할 수 있다.
  3. 코드 유지 보수성 : 스타일을 정의하는 코드와 해당 스타일을 사용하는 코드가 함께 있어서 코드 유지 보수성이 높아집니다.

리액트에서 CSS in JS를 구현하는 방법으로는 다양한 라이브러리가 있다. 대표적으로 Styled Components 외에도, Emotion, Glamorous, JSS 등이 있다.

Styled Components 란

Styled Components의 공식 홈페이지 바로가기

Styled Components - React 애플리케이션에서 CSS 스타일을 관리하기 위한 JavaScript 라이브러리!

리액트 프로젝트에 Styled Components 적용하기

  1. vs code에서 작업할 것이므로 우선, vs code에 vscode-styled-components 확장프로그램을 설치하자. 스타일의 구문 강조, 자동 완성 기능, 스타일 미리보기 기능 등을 제공해서 더욱 편리하게 styled Components를 사용할 수 있다.

  2. styled components를 적용할 프로젝트 디렉토리로 이동한다.

    해당 디렉토리에서 `yarn add styled-components 명령어를 실행한다.

package.json 파일에 잘 설치되어서 들어가있는 styled-components를 확인할 수 있다.

styled-components를 적용할 컴포넌트에 import 한다.

```jsx
// App.jsx
import './App.css';
import styled from 'styled-components';
function App() {

    return (
        <div>
        </div>
    );
}

export default App;
```

</br>

**변수선언자 식별자명 = 임포트해온이름.html 요소명 백틱** 으로 사용한다

```jsx
// App.jsx
import './App.css';
import styled from 'styled-components';
/** 
    변수선언자 식별자명 = 임포트한이름.html요소``
    styled 로 import 해온 styled-components를 div 태그에 적용해보자
 */
const StBox = styled.div`
    color : green;
    background-color: aqua;
    width: 100px;
    height: 100px;
    border: 1px solid black;
    margin: 10px;
    `
function App() {
    return (
                <>
            <div>
                        박스1
            </div>
            <StBox>
                        박스2
            </StBox>
                </>
    );
}

export default App;
```

</br>

식별자명으로 된 태그에 감싸진 박스2가 스타일이 입혀진 div 태그가 적용된다.
  • 기존의 jsx에서 inline 혹은 객체로 분리해서 스타일 작업을 하는 경우 기존의 CSS와 약간씩 다른 문법을 사용해야 해서 불편했는데 styled-component를 사용하니까 백틱 안에서 CSS문법을 그대로 사용할 수 있어서 좋은 것 같다.

자바스크립트 기능 적용

  1. props로 데이터 넘겨주기

    StBox는 자식컴포넌트 이므로 부모컴포넌트인 App 컴포넌트에서 데이터를 props로 넘겨줄 수 있다.

     import './App.css';
     import styled from 'styled-components';
    
     const StBox = styled.div`
       color : green;
       background-color: aqua;
       width: 100px;
       height: 100px;
       border: 1px solid ${(props) => props.borderColor};
       margin: 10px;
     `
     function App() {
         return (
             <>
                 <StBox borderColor="red">
                     박스1
                 </StBox>
                 <StBox borderColor="green">
                     박스2
                 </StBox>
                 <StBox borderColor="blue">
                     박스3
                 </StBox>
             </>
         );
     }
    
     export default App;

  2. map을 활용해서 반복적인 요소를 줄이자.

     import './App.css';
     import styled from 'styled-components';
    
     // div를 가운데 정렬하기 위해 추가
     const StWrap = styled.div`
       display: flex;
       align-items: center;
       justify-content: center;
     `
     // div 태그에 적용된 css
     const StBox = styled.div`
       color : green;
       background-color: aqua;
       width: 100px;
       height: 100px;
       border: 1px solid ${(props) => props.borderColor};
       margin: 10px;
     `
     // 박스의 색을 담은 배열
     const boxColorList = ['red', 'blue', 'green']
    
     // 배열의 값을 돌면서 적당한 박스 내용을 출력함.
     const getBoxName = function (color) {
         switch (color) {
             case 'red':
                 return "붉은색 박스"
             case 'blue':
                 return "푸른색 박스"
             case 'green':
                 return "초록색 박스"
             default:
                 return '투명한 박스'
         }
     }
    
     function App() {
         return (
             <StWrap>
                 {
                     boxColorList.map((box) => {
                         return <StBox borderColor={box}>{getBoxName(box)}</StBox>
                     })
                 }
             </StWrap>
         );
     }
    
     export default App;

전역 디자인 적용 GlobalStyles

  1. 디자인을 담은 컴포넌트를 생성한다.

     //components/TestStyle.jsx
     import React from 'react';
     import styled from 'styled-components';
    
     function TestPage(props) {
         return (
             <Wrapper>
                 <Title>{props.title}</Title>
                 <Contents>{props.contents}</Contents>
             </Wrapper>
         );
     }
    
     const Title = styled.h1`
         font-family: "Helvetica", "Arial", sans-serif;
         line-height: 1.5;
         font-size: 1.5rem;
         margin: 0;
         margin-bottom: 8px;
       `;
    
     const Contents = styled.p`
         margin: 0;
         font-family: "Helvetica", "Arial", sans-serif;
         line-height: 1.5;
         font-size: 1rem;
       `;
    
     const Wrapper = styled.div`
         border: 1px solid black;
         border-radius: 8px;
         padding: 20px;
         margin: 16px auto;
         max-width: 400px;
       `;
    
     export default TestPage;

  2. 반복되는 요소를 분리한다. 위 코드에서는 font-family와 line-height를 분리해보자. 반복되는 디자인 CSS를 담을 파일을 생성한다

     // GlobalStyle.jsx
     import { createGlobalStyle } from "styled-components";
    
     const GlobalStyle = createGlobalStyle`
        body {
             font-family: "Helvetica", "Arial", sans-serif;
             line-height: 2.5;
         }
     `
     export default GlobalStyle

  3. 공통으로 적용될 컴포넌트에 공통 디자인을 적용한다.

     // App.jsx
     import './App.css';
     import TestPage from './components/TestPage';
     import GlobalStyle from './GlobalStyle'
    
     function App() {
         return (
             <>
                 <GlobalStyle></GlobalStyle>
                 <TestPage title="쩨목입니다." contents="내용내용ㅇ" />
             </>
         );
     }
    
     export default App;

'개발 > React' 카테고리의 다른 글

[리액트] Hooks - useEffect  (3) 2023.04.25
[리액트] Hooks - useState  (0) 2023.04.24
[리액트] State  (0) 2023.04.15
[리액트] Props란, Prop Drilling (칸트 도덕철학)  (1) 2023.04.15
[리액트] JSX란? JSX문법 소개  (0) 2023.04.15