ReactJS

React - ( Styled - components )

jjangsh 2024. 8. 22. 21:40

01. CSS-in-JS란?

 

(1) css-in-js란 무엇일까?

CSS-in-JS방식이란, 단어 그대로 자바스크립트 코드로 CSS 코드를 작성하여 컴포넌트를 꾸미는 방식입니다. 순수한 CSS코드를 우리가 아니라, 자바스크립트를 이용해서 CSS코드를 만들어내는 것이죠. CSS-in-JS 방식을 사용하기 위해 우리는 새로운 패키지를 사용할 것입니다.

 

 ☝ css-in-js를 사용할 때, 이런 장점이 있어요!

기존에 css 파일을 작성하고, import하는 방식에서는 style을 작성할 때 조건문 등의 로직을 적용할 수 없었어요. 하지만, css-in-js를 사용함으로써 style을 적용할 때 조건문, 변수 등 다양한 로직을 이용할 수 있어요.

 

(2) styled-components란 무엇일까?

 

styled-components는 우리가 리액트에서 CSS-in-JS 방식으로 컴포넌트를 꾸밀 수 있게 도와주는 패키지입니다. 입니다. styled-components 외에도 다양한 패키지가 있지만, styled-components 예전부터 꾸준히 많은 개발자들에게 선택받은 패키지입니다.

 

 

패키지란, React에는 없는 기능이지만 우리가 추가로 가져와서 사용할 수 있는 써드파티 프로그램입니다. 패키지들은 누군가에 의해 만들어진 것으로 npm에 모여 있어요. 우리는 사용하고자 하는 패키지를 npm install 또는 yarn add를 통해서 설치해서 사용할 수 있어요. 앞으로 이렇게 React에서 자체적으로 제공하지 않지만, 사용하면 우리가 개발하는데 더 유용한 여러 패키지들이 있습니다.

 

 

02. styled-components

 

(1) 준비하기

(1)-1. VSCode 플러그인 설치

 

우리는 styled-components를 이용해서 코드를 작성할 때 조금 더 편하게 하기 위해 아래 플러그인을 설치하겠습니다. 이 플러그인 설치해야만 styled-components 안에서 스타일 코드를 편하게 작성할 수 있습니다.

 

 

(1)-2. yarn으로 styled-components 설치하기

 

vscode 터미널에서 아래 명령을 입력해서 패키지를 설치해 주세요.

yarn add styled-components

 

 

(2) 사용하기

(2)-1. 기본적인 사용법 알아보기

 

SC의 기본적인 원리는 꾸미고자 하는 컴포넌트를 SC의 방식대로 먼저 만들고, 그 안에 스타일 코드를 작성하는 방식으로 진행합니다. 코드를 보겠습니다.

// src/App.js

import React from "react";
// styled-components에서 styled 라는 키워드를 import 합니다.
import styled from "styled-components";

// styled키워드를 사용해서 styled-components 방식대로 컴포넌트를 만듭니다. 
const StBox = styled.div`
	// 그리고 이 안에 스타일 코드를 작성합니다. 스타일 코드는 우리가 알고 있는 css와 동일합니다.
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin: 20px;
`;

const App = () => {
	// 그리고 우리가 만든 styled-components를 JSX에서 html 태그를 사용하듯이 사용합니다.
  return <StBox>박스</StBox>;
};

export default App;

 

위와 같이 코드를 작성하고 브라우저를 보면, 아래와 같이 스타일링이 된 컴포넌트를 볼 수 있습니다.

가장 핵심이 되는 코드는 const StBox = styled.div``; 이 부분입니다. 처음 보면 참 이상하게 생겼죠? 하지만 이 방식대로 styled-components를 만드는 것이 맞습니다! 참고로 `` 은 따옴표가 아니라 '백틱'이라는 문자입니다.

 

그리고 styled. 뒤에는 html의 태그가 옵니다. 아래처럼 내가 원하는 html 태그를 사용해서 styled-components를 만들 수 있습니다.

 

div ➡️ styled.div

span ➡️ styled.span

button ➡️ styled.button

 

 

(2)-2. 조건부 스타일링이란?

 

classname을 사용해서 구현하기는 조금 까다로운 조건부 스타일링을 styled-components를 이용하면 간편하게 할 수 있습니다. 만약에 스타일 코드를 작성할 때 if문을 사용할 수 있다면? , switch문을 사용할 수 있다면? , 삼항연산자를 사용할 수 있다면?

CSS-in-JS 방식의 강점이 바로 스타일 코드를 JS코드 작성하듯이 스타일 코드를 작성할 수 있다는 점입니다.

 

 

(2)-3. 조건부 스타일링 구현해 보기

 

위 이미지에 보이는 red, green, blue border를 가진 박스를 구현해 보겠습니다. 내가 컴포넌트한테 “넌 red야" 라고 하면 red box가 되고, “넌 green box야"라고 말하면 green box가 되게끔 어떻게 해야 할까요?

 

props는 부모 컴포넌트에서 자식 컴포넌트로 어떤 정보를 전달하고자 할 때 사용합니다. styled-components도 말 그대로 컴포넌트입니다. 입니다. 즉, 우리는 box들에게 prosp를 통해서 border color에 대한 정보를 전달해 줄 수 있다는 말입니다.

 

// src/App.js

import React from "react";
import styled from "styled-components";

// 1. styled-components를 만들었습니다.
const StBox = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid ${(props) => props.borderColor}; // 4.부모 컴포넌트에서 보낸 props를 받아 사용합니다. 
  margin: 20px;
`;

const App = () => {
  return (
    <div>
			{/* 2. 그리고 위에서 만든 styled-components를 사용했습니다. */}
			{/* 3. 그리고 props를 통해 borderColor라는 값을 전달했습니다. */}
      <StBox borderColor="red">빨간 박스</StBox>
      <StBox borderColor="green">초록 박스</StBox>
      <StBox borderColor="blue">파랑 박스</StBox>
    </div>
  );
};

export default App;

 

위 코드를 분석하자면

 

1. 먼저 styled-component를 생성합니다.

const StBox = styled.div``;

 

2. 그리고 생성한 styled-component를 부모 컴포넌트에서 사용합니다. 여기서 부모컴포넌트는 App.js 입니다.

const App = () => {
  return (
    <div>
      <StBox>빨간 박스</StBox>
      <StBox>초록 박스</StBox>
      <StBox>파랑 박스</StBox>
    </div>
  );
};

 

3. 그리고 이제 우리가 원하는 값, 즉 borderColor를 props로 자식컴포넌트, 여기서는 자식컴포넌트가 styled-components 겠죠? StBox에 전달합니다

const App = () => {
  return (
    <div>
      <StBox borderColor="red">빨간 박스</StBox>
      <StBox borderColor="green">초록 박스</StBox>
      <StBox borderColor="blue">파랑 박스</StBox>
    </div>
  );
};

 

4. 부모 컴포넌트에서 props를 보냈습니다. 자식 컴포넌트에서는 받아야겠죠? 아래와 같은 모양으로 받습니다. 

const StBox = styled.div`
  border: 1px solid ${(props) => props.borderColor};
`;

 

1. 첫째, 먼저 자바스크립트 코드를 사용하기 위해 ${ } 를 열어줍니다.

 

2. 둘째, 비어있는 화살표 함수를 열어 줍니다. ${( )=>{ }} 

 

3. 셋째, 함수의 인자에서 props를 받아오고, props안에는 부모 컴포넌트에서 보낸 borderColor가 있습니다. 그것을 return 합니다. ${(props)⇒{ return props.borderColor }} 이렇게 리턴하면 (props)⇒{ return props.borderColor } 의 값이 === 'red' 가 되고 결국 우리 눈에는 복잡해 보이지만, 브라우저는 border: 1px solid red 라는 코드로 인식하여 스타일링이 되는 것입니다.

 

(2)-4 Swtich문과 map을 사용해서 리팩토링 해보기

 

위에서 구현한 코드를 자바스크립트의 map과 switch문을 이용해서 리팩토링 했습니다.

// src/App.js

import React from "react";
import styled from "styled-components";

const StContainer = styled.div`
  display: flex;
`;

const StBox = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid ${(props) => props.borderColor};
  margin: 20px;
`;
// 박스의 색을 배열에 담습니다.
const boxList = ["red", "green", "blue"];

// 색을 넣으면, 이름을 반환해주는 함수를 만듭니다.
const getBoxName = (color) => {
  switch (color) {
    case "red":
      return "빨간 박스";
    case "green":
      return "초록 박스";
    case "blue":
      return "파란 박스";
    default:
      return "검정 박스";
   }
};
const App = () => {
  return (
    <StContainer>
			{/* map을 이용해서 StBox를 반복하여 화면에 그립니다. */}
      {boxList.map((box) => (
        <StBox borderColor={box}>{getBoxName(box)}</StBox>
      ))}
    </StContainer>
  );
};

export default App;

 

 

 

03. GlobalStyles(전역 스타일링)

 

(1) 전역 스타일링이란?

styled components는 컴포넌트 내에서만 활용할 수 있었어요. 하지만 가끔 우리는 프로젝트를 아우르는, 공통적으로 들어가야 할 스타일을 적용해야 할 필요도 있습니다. 그럴 경우 ‘전역적으로(globally)’ 스타일을 지정한다.라고 표현하는데요. 그럴 때 적용하는 방법이 바로 전역 스타일링이에요.

 

(2) 컴포넌트 단위 스타일링

먼저 기존까지 사용했던 컴포넌트 단위의 스타일링 기법을 살펴볼게요.

다음 <TestPage /> 컴포넌트를 보겠습니다.

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;

 

<h1>, <p>, <div> 태그는 각각 <Title />, <Contents />, <Wrapper />에서 새롭게 스타일링 되었군요.

 

만일 규모가 좀 큰 프로젝트라고 한다면 공통적으로 적용되는 스타일링 부분은 빼줄 필요가 있습니다. 우리의 경우는 글꼴(font)와 line-height를 공통 요소라 가정하고 GlobalStyles을 적용해 보겠습니다.

 

(3) GlobalStyles 적용

GlobalStyle.jsx

import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    font-family: "Helvetica", "Arial", sans-serif;
    line-height: 1.5;
  }
`;

export default GlobalStyle;

 

BlogPost.jsx

function BlogPost({ title, contents }) {
  return (
    <>
      <p>{title}</p>
      <p>{contents}</p>
    </>
  );
}

export default App;

 

App.jsx

import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";

function App() {
	const title = '전역 스타일링 제목입니다.';
	const contents = '전역 스타일링 내용입니다.';
  return (
    <>
      <GlobalStyle />
      <BlogPost title={title} contents={contents} />
    </>
  );
}

export default App;

 

 

04. css reset

 

(1) css reset이란?

브라우저는 기본적으로 default style을 제공해요. 예를 들면 margin이나 글자의 크기 같은 경우죠.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    Default Style을 테스트 해 봅니다.
    <h1>이건 h1 태그에요</h1>
    <p>이건 p 태그에요</p>
  </body>
</html>

 

 

다양한 웹브라우저들은 저마다 조금씩은 다른 default style을 제공하고 있기 때문에 이를 초기화하고 우리가 정하는 대로만 표현되는 것이 중요해요!

 

(2) css 초기화하기

초기화하는 방법은 여러 가지가 있지만, 아래 코드를 한번 사용해 볼게요.

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./reset.css" />
  </head>
  <body>
    <span>Default Style을 테스트 해 봅니다.</span>
    <h1>이건 h1 태그에요</h1>
    <p>이건 p 태그에요</p>
  </body>
</html>

 

 

아래 이미지처럼 h1과 p태그의 기본 스타일링이 해제된 것을 볼 수 있습니다.

 

'ReactJS' 카테고리의 다른 글

React - ( React Hooks 2 - useEffect )  (1) 2024.08.26
React - ( React Hooks 1 - useState )  (0) 2024.08.23
React - DOM과 Virtual DOM  (0) 2024.08.21
React - 컴포넌트 및 렌더링  (0) 2024.08.21
React - state  (0) 2024.08.21