ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React Custom Component : Styled Components
    Front-End👩🏻‍💻/React👩🏻‍💻 2022. 6. 30. 14:21
    728x90

    Component Driven Development(CDD)컴포넌트주도개발

    회사에서 페이지 개발을 하던 중 다른 페이지에 적용되었던 버튼을 새로운 페이지에 추가하려고 한다.

    이때 같은 UI컴포넌트를 공유하면 새로 개발하지 않아도 된다.

    = 재사용할 수 있는 UI컴포넌트 = 부품 단위로 UI 컴포넌트를 만들어 나가는 개발

    CDD를 활용한 개발 방법은 컴포넌트 단위로 만들어 페이지를 조립하는 개발 방식인 상향식 개발에 가깝다.

    구조적인 CSS 작성 방법의 발전

    기술의 발달과 함께 다양한 환경에서 인터넷을 사용하기 시작하면서 CSS 작성방식도 발전하고있다.

    또,함께 일하는 사람들도 많아지면서 css 는 양도 많고 더 복잡해졌고, 다양한 디바이스의 등장으로 웹사이트들이 다양한 디스플레이를 커버 해야되서 css는 훨씬 더 복잡해졌다. 따라서 css 작업을 효율적으로 하기 위해 구조화 된 CSS의 필요성이 대두되었고, CSS를 구조화하는 방법에 대한 연구가 시작되었다.

    CSS 구조화를 위한 다양한 시도

    이런 문제를 해결하기 위해 CSS 전처리기(CSS Preprocessor)가 나왔다.

    CSS가 구조적으로 작성 될 수 있게 도움을 주는 도구

    하지만 CSS전처리기 자체만으로는 웹 서버가 인지하지 못하기 때문에 각 CSS전처리기에 맞는 Compiler 를 사용해야 하고 컴파일을 하게 되면 실제로 우리가 사용하는 CSS 문서로 변환이 된다.

    이를 통해 CSS파일들을 잘 구조화 할 수 있게 되었고, 최소한 CSS 파일을 몇 개의 작은 파일로 분리할 수 있는 방법이 생겼다.

    • SASS(Syntactically Awesome Style Sheets)

    CSS를 확장해주는 스크립팅 언어이다.

    즉, CSS를 만들어주는 언어로서 자바스크립트처럼 특정 속성(ex. color, margin, width 등)의 값ex. #ffffff, 25rem, 100px 등)을 변수로 선언하여 필요한 곳에 선언 된 변수를 적용할 수도 있고, 반복되는 코드를 한번의 선언으로 여러 곳에서 재사용 할 수 있도록 해주는 기능을 가졌다. 그래서SASS는 SCSS 코드를 읽어서 전처리한 다음 컴파일해서 전역 CSS 번들 파일을 만들어 주는 전처리기(preprocessor)의 역할을 한다.

    하지만 얼마 지나지 않아서 SASS가 ‘CSS의 구조화’를 해결해 주는 것의 장점보다 다른 문제들을 더 많이 만들어낸다는 것을 알았고, 결국 우리는 전처리기(preprocessor)가 내부에서 어떤 작업을 하는지는 알지 못한 채, 스타일이 겹치는 문제를 해결하기 위해 단순히 계층 구조를 만들어 내는 것에 의지하게 되었고, 그 결과 컴파일된 CSS의 용량은 더욱 커지게 되었다.

    CSS 전처리기의 문제를 보완하기 위해 BEM, OOCSS, SMACSS 같은 CSS 방법론이 대두

    방법론의 공통 지향점

    -코드의 재사용

    -코드의 간결화(유지 보수 용이)

    -코드의 확장성

    -코드의 예측성(클래스 명으로 의미 예측)

    • BEM

    Block, Element, Modifier 로 구분하여 클래스명을 작성하는 방법 각각 -와_로 구분한다.
    Block : 전체를 감싸고 있는 블럭 요소
    Element : 블럭이 포함하고 있는 한 조각
    Modifier : 블럭 또는 요소의 속성
    (블록이나 엘리먼트의 외관이나 상태를 변화 가능하게 하는 부분)

    클래스명은 BEM 방식의 이름을 여러 번 반복하여 재사용할 수 있도록 하며 HTML/CSS/SASS 파일에서도 더 일관된 코딩 구조를 만들어 준다. 하지만 클래스명 선택자가 장황해지고, 이런 긴 클래스명 때문에 마크업이 불필요하게 커지며, 재사용하려고 할 때마다 모든 UI 컴포넌트를 명시적으로 확장해야 했다.

    여전히 해결되지 않았던 문제들은 언어 로직 상에 진정한 캡슐화(encapsulation : 객체의 속성과 행위를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하는 개념)의 개념이 없다는 것으로 인해 개발자들은 유일한 클래스명을 선택하는 것에 의존했다.

    • CSS-in-JS 등장 <Styled-Component>

    기능적(Functional) 혹은 상태를 가진 컴포넌트들로부터 UI를 완전히 분리해 사용할 수 있는 아주 단순한 패턴을 제공한다.

      특징 장점 단점
    CSS 기본적인 스타일링 방법 - 일관된 패턴을 갖기 어려움. !important의 남용
    SASS(preprocessor) 프로그래밍 방법론을 도입하여, 컴파일된 CSS를 만들어내는 전처리기 변수/함수/상속 개념을 활용하여 재사용 가능 CSS의 구조화 전처리과정 필요, 디버깅의 어려움이 있음, 컴파일한 CSS파일이 거대해짐
    BEM CSS클래스명 작성에 일관된 패턴을 강제하는 방법론 네이밍으로 문제해결, 전처리 과정 불필요 선택자의 이름이 장황하고, 클래스 목록이 너무 많아짐
    Styled-Component (CSS-in-JS) 컴포넌트 기반으로 CSS를 작성할 수 있게 도와주는 라이브러리 CSS를 컴포넌트 안으로 캡슐화, 네이밍이나 최적화를 신경 쓸 필요가 없음 빠른 페이지 로드에 불리함

    Styled Components

    CSS코드를 다룰 때 불편했던 점들(class,id이름짓기, CSS파일 안에서 원하는 부분 찾기 등)을 CSS 컴포넌트화 시킴으로써 해결해주는 라이브러리이다.

    앞에 나왔 던 CSS in JS 라는 개념이 대두되면서 나온 라이브러리이다.

    CSS in JS 라이브러리를 사용하면 CSS도 쉽게 JavaScript 안에 넣어줄 수 있으므로, HTML+JS+CSS 까지 하나의 JS 파일 안에서 컴포넌트 단위로 개발할 수 있게 된다.

    Styled Components 설치하기

    # with npm
    $ npm install --save styled-components
    

    Styled Components는 package.json에 다음 코드를 추가하도록 권장한다.

    코드를 추가하면 여러 버전의 Styled Components가 설치되어 발생하는 문제를 줄여준다.

    {
      "resolutions": {
        "styled-components": "^5"
      }
    }
    

    그 다음 Styled Components를 사용할 파일로 불러와주면 사용 준비는 완료

    import styled from "styled-components"
    

    Styled Components 문법

    1. 컴포넌트 만들기
    //ES6의 Templete Literals 문법을 사용 ``백틱
    const 컴포넌트이름 = styled.태그종류`
    	CSS속성1 : 속성값;
    	CSS속성2 : 속성값;
    `;
    ____________________________________________
    
    import styled from "styled-components";
    
    //Styled Components로 컴포넌트를 만들고
    
    const BlueButton = styled.button`
      background-color: blue;
      color: white;
    `;
    
    export default function App() {
      // React 컴포넌트를 사용하듯이 사용하면 됩니다.
      return <BlueButton>Blue Button</BlueButton>;
    }
    

      2. 컴포넌트를 재활용해서 새로운컴포넌트 만들기

    const 컴포넌트이름 = style(재활용할 컴포넌트)`
    	추가할 css속성1 : 속성값;
    	추가할 css속성2 : 속성값;
    `;
    ____________________________________________
    
    import styled from "styled-components";
    
    const BlueButton = styled.button`
      background-color: blue;
      color: white;
    `;
    
    //만들어진 컴포넌트를 재활용해 컴포넌트를 만들 수 있습니다.
    const BigBlueButton = styled(BlueButton)`
      padding: 10px;
      margin-top: 10px;
    `;
    
    //재활용한 컴포넌트를 재활용할 수도 있습니다.
    const BigRedButton = styled(BigBlueButton)`
      background-color: red;
    `;
    
    export default function App() {
      return (
        <>
          <BlueButton>Blue Button</BlueButton>
          <br />
          <BigBlueButton>Big Blue Button</BigBlueButton>
          <br />
          <BigRedButton>Big Red Button</BigRedButton>
        </>
      );
    }
    

       3. Props 활용하기

    Styled Component로 만든 컴포넌트도 React 컴포넌트처럼 props를 내려줄 수 있다. 내려준 props 값에 따라서 컴포넌트를 렌더링하는 것도 가능하다.

    //Styled Components는 템플릿 리터럴 문법( ${ } )을 사용하여 
    //JavaScript 코드를 사용할 수 있다.
    const 컴포넌트이름 = style.태그종류 `
    	css속성 : ${(props)=>함수코드}
    `;
    

        1) props로 조건부 렌더링하기

    //삼항연산자를 활용해 <Button> 컴포넌트에 
    //skyblue 라는 props가 있는지 확인하고, 
    //있으면 배경색으로 skyblue를, 없을 경우 white를 지정해주는 코드
    const Button = style.button`
    	background : ${(props)=>props.skyblue ? "skyblue":"white"}
    `;
    _____________________________________________________________
    
    import styled from "styled-components";
    import GlobalStyle from "./GlobalStyle";
    //받아온 prop에 따라 조건부 렌더링이 가능합니다.
    const Button1 = styled.button`
      background: ${(props) => (props.skyblue ? "skyblue" : "white")};
    `;
    
    export default function App() {
      return (
        <>
          <GlobalStyle />
          <Button1>Button1</Button1>
          <Button1 skyblue>Button1</Button1>
        </>
      );
    }
    //Button1 의 경우는 skyblue 라는 props가 있어 배경색이 skyblue 로 지정됐고,
    //Button2의 경우는 props가 아예 없어 배경색이 white 로 지정된 것
    

        2) Props 값으로 렌더링하기

    //이번에는 props.color 가 없다면 white를, props.color 가 있다면 
    //props.color의 값을 그대로 가져와서 스타일 속성 값으로 리턴
    import styled from "styled-components";
    import GlobalStyle from "./GlobalStyle";
    
    //받아온 prop 값을 그대로 이용해 렌더링할 수도 있습니다
    const Button1 = styled.button`
      background: ${(props) => (props.color ? props.color : "white")};
    `;
    //다음과 같은 형식으로도 활용할 수 있습니다.
    const Button2 = styled.button`
      background: ${(props) => props.color || "white"};
    `;
    
    export default function App() {
      return (
        <>
          <GlobalStyle />
          <Button1>Button1</Button1>
          <Button1 color="orange">Button1</Button1>
          <Button1 color="tomato">Button1</Button1>
          <br />
          <Button2>Button2</Button2>
          <Button2 color="pink">Button2</Button2>
          <Button2 color="turquoise">Button2</Button2>
        </>
      );
    }
    

        4. 전역스타일 설정하기

    스타일을 컴포넌트로 만들 수 있다는 것은 좋지만, 전역에 스타일을 설정하고 싶을 땐

    createGlobalStyle함수를 불러온다.

    import { createGlobalStyle } from "styled-components";
    
    const GlobalStyle = createGlobalStyle`
    	button {
    		padding : 5px;
        margin : 2px;
        border-radius : 5px;
    	}
    `
    //<GlobalStyle> 컴포넌트를 최상위 컴포넌트에서 사용해주면 전역에 
    //<GlobalStyle> 컴포넌트의 스타일이 적용
    function App() {
    	return (
    		<>
    			<GlobalStyle />
    			<Button>전역 스타일 적용하기</Button>
    		</>
    	);
    }
    
    /* hover : 마우스를 대면 효과가 생긴다. */
      &:hover {
        background: cornflowerblue;
        color: white;
        transition: 0.5s;
      }
    
    728x90

    'Front-End👩🏻‍💻 > React👩🏻‍💻' 카테고리의 다른 글

    React useRef  (0) 2022.07.04
    CDD개발도구 : Storybook  (0) 2022.07.01
    Unit9 - [React] 클라이언트 Ajax 요청  (0) 2022.06.14
    Unit5 - [React] React SPA  (0) 2022.06.03
    Unit 4 - [React] Intro  (0) 2022.06.02
Designed by Tistory.