[ReactJS] styled-components와 함께 하는 즐거운 ReactJS

2022. 7. 12. 04:31·Learning-Log/Computer Science
728x90
320x100

styled-components를 이용하지 않고 React만을 통해서 웹 퍼블리싱을 하는 방법은 크게 3가지가 있다.
해서... 원래는 3가지 방법을 모두 설명하려 했지만.... 다음에 기회가 되면 하기로 하고, 바로 styled-components로 들어가보자. 

어차피 지금 시점에서 React를 쓰면서, styled-components 를 쓰지 않는다는 것은 어불성설이다. 

설치

npm i styled-components

주의할 점이 딱 하나 있다. styled-component가 아니라 styled-components 이다. 맨 끝에 s가 반드시 붙어야한다.

실제로 npm 에 styled-component라는 패키지가 이미 존재한다. 따라서 주의가 필요하다. 뭐 악성프로그램은 아니지만, 더 이상 관리가 되지 않는 패키지이며, 우리가 쓰려는 패키지가 아니다!

 

기본 문법

const Alias = styled.div`
    width: 100px;
    height: 100px;
`;

function App() {
    return(
        <div>
            <Alias></Alias>
        </div>
    );
}

////위 문법은 아래와 정확히 같은 기능을 수행한다

function App() {
    return(
        <div>
            <div style={{width : 100, height : 100}}>
            </div>
        </div>
    );
}

보다시피 styled의 메서드로 원하는 HTML 태그를 적어준 뒤 Back Tick 안에 구현하고 싶은 CSS 문법을 그대로 써주면 된다!

참고로 <Alias></Alias>로 쓰나, <Alias />로 쓰나 동일하다. 후자가 전자의 short-cut 인 셈.

 

응용

말 그대로, 스타일이 입혀진 컴포넌트(styled-components)를 응용하는 방법을 알아보자.

 

1. Props 활용하기

스타일의 대부분이 비슷하게 겹치는 와중에 한 두개만 달라지는 경우 아래 방법을 유용하게 쓸 수 있다.
가령, 똑같은 디자인의 네모 상자를 두 개 만들고 이들의 색상만 달리하고 싶다면 아래와 같이 작성하면 된다.

import styled from "styled-components";

const Alias = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

function App() {
  return (
    <div>
      <Alias color="blue" />
      <Alias color="red" />
    </div>
  );
}

export default App;

눈치 챘겠지만, 그냥 props를 통해 옵션을 전달한 것 뿐이다.

 

2. 확장하기

이번에는 확장하는 방법이다. 마치 class 의 상속과 같다. 즉, 여기서 말하는 확장이란, 확장의 대상이 되는 컴포넌트의 모든 CSS 설정을 그대로 승계한 뒤, 독자적인 CSS 설정을 추가하는 것을 의미한다.

import styled from "styled-components";

const Square = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

const Circle = styled(Square)`
  border-radius: 50px;
`;

function App() {
  return (
    <div>
      <Square color="blue" />
      <Circle color="red" />
    </div>
  );
}

export default App;

Circle 부분을 유심히 보자. styled에서 이번에는 메서드로 접근하지 않고, styled 함수의 인자로 확장하고 싶은 styled-component인 Square를 전달해주었다. 그리고 해당 컴포넌트에 추가하고 싶은 스타일을 Back Tick 안에 적으면 끝.

 

3. 태그 바꿔쓰기

내 맘대로 태그 바꿔쓰기가 가능하다. props 를 전달할 때, as라는 props 명으로 원하는 HTML 태그를 전달하면 된다.

import styled from "styled-components";

const Square = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

const Circle = styled(Square)`
  border-radius: 50px;
`;

function App() {
  return (
    <div>
      <Square color="blue" />
      <Circle color="red" as="button">
        Push
      </Circle>
    </div>
  );
}

export default App;

Circle 컴포넌트에서 as를 통해 button 태그를 할당해주었다. 그랬더니 아래와 같이 div가 아닌 button 태그로 HTML이 작성된 모습을 확인할 수 있다.

 

4. 공통 속성 추가하기

styled-components의 기본 문법에서 HTML태그 부분 하위에는 하나의 메서드가 더 존재한다. 바로 attrs 메서드. 
아래와 같이 작성하면, attrs에 적힌 속성을 공통으로 추가 가능하다.

import styled from "styled-components";

const Square = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

const Diamond = styled(Square).attrs({ value: "yes" })`
  transform: rotate(45deg);
  margin: 20px;
`;

function App() {
  return (
    <div>
      <Diamond color="red" as="button" />
      <Diamond color="green" as="button" />
      <Diamond color="yellow" as="button" />
      <Diamond color="black" as="button" />
      <Diamond color="wheat" as="button" />
      <Diamond color="tomato" as="button" />
      <Diamond color="blue" as="button" />
      <Diamond color="orange" as="button" />
      <Diamond color="navy" as="button" />
    </div>
  );
}

export default App;

 

5. 애니메이션 추가하기

 

300x250

 

styled-components로부터 styled 뿐만 아니라 keyframes를 추가로 import 해주자. 

import styled, {keyframes} from 'styled-components'

 

그 후 애니메이션을 설명하는 변수를 하나 만들어준다.

const ani = keyframes`
	CSS 코드로 작성한 애니메이션
`

 

이렇게 선언된 변수를 애니메이션을 넣고 싶은 컴포넌트의 styled에 추가해주면 끝.

import styled, { keyframes } from "styled-components";

const ani = keyframes`
0% {
  border-radius:0px;
}
50%{
  border-radius:100px;
}
100%{
  border-radius:0px;
}
`;
const Square = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

const Diamond = styled(Square).attrs({ value: "yes" })`
  transform: rotate(45deg);
  margin: 20px;
  animation: ${ani} 1s linear infinite;
`;

function App() {
  return (
    <div>
      <Diamond color="red" as="button" />
      <Diamond color="green" as="button" />
      <Diamond color="yellow" as="button" />
      <Diamond color="black" as="button" />
      <Diamond color="wheat" as="button" />
      <Diamond color="tomato" as="button" />
      <Diamond color="blue" as="button" />
      <Diamond color="orange" as="button" />
      <Diamond color="navy" as="button" />
    </div>
  );
}

export default App;

6. SCSS 문법의 구현

기본적으로 styled-components 문법은 Back Tick 안에 있는 코드를 CSS로 전환시키는데, 이 과정에서 SCSS의 문법을 차용하여 개발 생산성을 끌어올렸다. 

참고로 아래와 같은 문법을 Pseudo Selector라고 부르긴 한다.

import styled, { keyframes } from "styled-components";

const ani = keyframes`
0% {
  border-radius:0px;
}
50%{
  border-radius:100px;
}
100%{
  border-radius:0px;
}
`;
const Square = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

const Diamond = styled(Square).attrs({ value: "yes" })`
  transform: rotate(45deg);
  margin: 20px;
  animation: ${ani} 1s linear infinite;
  span {
    font-size: 40px;
    &:hover {
      font-weight: bolder;
    }
  }
`;

function App() {
  return (
    <div>
      <Diamond color="red" as="button" />
      <Diamond color="green" as="button" />
      <Diamond color="yellow" as="button" />
      <Diamond color="black" as="button" />
      <Diamond color="wheat" as="button">
        <span>Hi</span>
      </Diamond>
      <Diamond color="tomato" as="button" />
      <Diamond color="blue" as="button" />
      <Diamond color="orange" as="button" />
      <Diamond color="navy" as="button" />
    </div>
  );
}

export default App;

 

참고로, span 대신에 styled-components 로 만든 컴포넌트가 오는 것은 당연히 가능하다!

import styled, { keyframes } from "styled-components";

const ani = keyframes`
0% {
  border-radius:0px;
}
50%{
  border-radius:100px;
}
100%{
  border-radius:0px;
}
`;

const Hello = styled.span`
  font-size: 40px;
`;

const Square = styled.div`
  background-color: ${(props) => props.color};
  width: 100px;
  height: 100px;
`;

const Diamond = styled(Square).attrs({ value: "yes" })`
  transform: rotate(45deg);
  margin: 20px;
  animation: ${ani} 1s linear infinite;
  ${Hello}:hover {
    font-weight: bolder;
  }
`;

function App() {
  return (
    <div>
      <Diamond color="red" as="button" />
      <Diamond color="green" as="button" />
      <Diamond color="yellow" as="button" />
      <Diamond color="black" as="button" />
      <Diamond color="wheat" as="button">
        <Hello>Hi</Hello>
      </Diamond>
      <Diamond color="tomato" as="button" />
      <Diamond color="blue" as="button" />
      <Diamond color="orange" as="button" />
      <Diamond color="navy" as="button" />
    </div>
  );
}

export default App;

 

7. GlobalStyle 만들기

styled-components는 본질적으로 css설정을 각 컴포넌트 단위로 분리시켜준다. 하지만, 가끔은 웹페이지 전체에 공통으로 적용할 글로벌 설정이 필요하다. 그럴때 필요한 것이 바로 GlobalStyle이다.

const GlobalStyle = createGlobalStyle`
 CSS 코드
 `

이렇게 작성한 GlobalStyle은 Fragment 문법으로 적용하면 된다.(컴포넌트의 병렬적 나열)

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'Learning-Log > Computer Science' 카테고리의 다른 글

[ReactJS] react-router의 useParams 에 대해 알아보자  (0) 2022.07.16
[JS] 모듈을 받아오는 import와 모듈을 내보내는 export  (0) 2022.07.15
[NestJS] NestJS, 한 번 빠지면 벗어날 수 없는 마성의 늪(3) : NestJS를 이해하기 위한 First Class Function, Closure 그리고 Decorator  (0) 2022.07.11
[NestJS] NestJS, 한 번 빠지면 벗어날 수 없는 마성의 늪(2) : NestJS 시작하기 & Express 프로젝트를 Nest로 마이그레이션 하는 경우  (0) 2022.07.11
[WSL] Ubuntu에서 현재 디렉토리를 윈도우 탐색기로 열기  (1) 2022.07.11
'Learning-Log/Computer Science' 카테고리의 다른 글
  • [ReactJS] react-router의 useParams 에 대해 알아보자
  • [JS] 모듈을 받아오는 import와 모듈을 내보내는 export
  • [NestJS] NestJS, 한 번 빠지면 벗어날 수 없는 마성의 늪(3) : NestJS를 이해하기 위한 First Class Function, Closure 그리고 Decorator
  • [NestJS] NestJS, 한 번 빠지면 벗어날 수 없는 마성의 늪(2) : NestJS 시작하기 & Express 프로젝트를 Nest로 마이그레이션 하는 경우
Xpectation
Xpectation
理
    반응형
    250x250
  • Xpectation
    자기실현적 기대
    Xpectation
  • 전체
    오늘
    어제
    • 전체보기 (213)
      • Thinking-Log (42)
        • 인간에 관한 생각 (22)
        • 사회현상에 관한 생각 (9)
        • 말씀에 관한 생각 (4)
        • 기타 잡념 (7)
      • Trading-Log (8)
        • 주식 잡념 (9)
      • Learning-Log (104)
        • Computer Science (70)
        • Economics (21)
        • Law (1)
        • ETC (12)
      • Review-Log (42)
        • 食思味 (13)
        • 聽思聰 (6)
        • 視思明 (12)
        • IT 제품, 전자기기 (6)
        • 게임 (0)
        • 기타 (5)
      • Creating-Log (5)
        • 주방 (0)
        • 서재 (5)
        • 기타 (0)
      • Photo-Log (3)
        • 사진 일기 (3)
      • 미분류 (0)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 태그
  • 링크

    • 티스토리 홈
  • 공지사항

  • 인기 글

  • 태그

    딥러닝
    마인드위즈Pro
    매매일지
    ASMR
    클래식음악
    주식
    티스토리챌린지
    오블완
    경제학
    수면유도
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
Xpectation
[ReactJS] styled-components와 함께 하는 즐거운 ReactJS
상단으로

티스토리툴바