CDD 개발도구

HIHI JIN·2023년 2월 20일
1

react

목록 보기
1/19
post-thumbnail

[React] Custom Component

Styled Components

Styled Components는 CSS in JS 라는 개념이 대두되면서 나온 라이브러리
기존에 HTML, CSS, JS 파일로 쪼개서 개발하던 방법에서, React 등의 라이브러리의 등장으로 컴포넌트 단위 개발이 주류가 되었지만, CSS는 그렇지 못했다.
CSS in JS 라이브러리를 사용하면 CSS도 쉽게 Javascript 안에 넣어줄 수 있으므로, HTML + JS + CSS까지 묶어서 하나의 JS파일 안에서 컴포넌트 단위로 개발할 수 있게 됩니다. 이런 CSS in JS 라이브러리 중에서 현재 가장 인기 있는 라이브러리가 바로 Styled Components 입니다.

Styled Components 설치하기

Styled Components는 package.json에 다음 코드를 추가하도록 권장하고 있습니다. 아래의 코드를 추가하면 여러 버전의 Styled Components가 설치되어 발생하는 문제를 줄여줍니다.

Styled Components 문법

1. 컴포넌트 만들기

Styled Components는 ES6의 Templete Literals 문법을 사용합니다.
즉, 따옴표가 아닌 백틱(`)을 사용합니다.
컴포넌트를 선언한 후 styled.태그종류를 할당하고, 백틱 안에 기존에 CSS를 작성하던 문법과 똑같이 스타일 속성을 작성해주면 됩니다.
이렇게 만든 컴포넌트를 React 컴포넌트를 사용하듯 리턴문 안에 작성해주면 스타일이 적용된 컴포넌트가 렌더되는 것을 확인할 수 있습니다.

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. 컴포넌트를 재활용해서 새로운 컴포넌트 만들기

이미 만들어진 컴포넌트를 재활용해서 새로운 컴포넌트를 만들 수도 있습니다. 컴포넌트를 선언하고 styled() 에 재활용할 컴포넌트를 전달해준 다음, 추가하고 싶은 스타일 속성을 작성해주면 됩니다.

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 코드를 사용할 수 있습니다. props를 받아오려면 props를 인자로 받는 함수를 만들어 사용하면 됩니다.

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

위 코드의 경우는 삼항연산자를 활용해
Button 컴포넌트에 skyblue 라는 props가 있는지 확인하고,
있으면 배경색으로 skyblue를, 없을 경우 white를 지정해주는 코드입니다.
이 코드에 따라 렌더링된 Button 컴포넌트는 아래 그림과 같을 것입니다.

Button1 의 경우는 skyblue 라는 props가 있어 배경색이 skyblue 로 지정됐고,
Button2의 경우는 props가 아예 없어 배경색이 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>
    </>
  );
}
2) Props 값으로 렌더링하기
props의 값을 통째로 활용해서 컴포넌트 렌더링에 활용할 수 있습니다. 똑같이 삼항연산자를 사용하고 있지만, 이번에는 props.color 가 없다면 white를, props.color 가 있다면 props.color의 값을 그대로 가져와서 스타일 속성 값으로 리턴해주고 있는 것을 볼 수 있습니다. 그 결과 color 라는 이름으로 받은 props의 값으로 배경색이 지정된 것을 확인할 수 있습니다. 꼭 삼항연산자만 사용해야하는 것은 아닙니다. JavaScript 코드라면 무엇이든 사용할 수 있으므로 원하는 값을 사용할 수 있도록 함수 코드를 만들어서 사용하면 됩니다. 따라서 위 예시와 같은 코드도 활용할 수 있을 것입니다. props도 원하는 만큼 받아서 사용할 수 있으니 다양하게 활용해보세요.
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. 전역 스타일 설정하기

스타일을 컴포넌트로 만들 수 있다는 것은 좋지만, 전역에 스타일을 설정하고 싶을 때는, 먼저 Styled Components에서 createGlobalStyle 함수를 불러옵니다.
다음 함수를 사용해 CSS 파일에서 작성하듯 설정해주고 싶은 스타일을 작성합니다.
이렇게 만들어진 GlobalStyle 컴포넌트를 최상위 컴포넌트에서 사용해주면 전역에 GlobalStyle 컴포넌트의 스타일이 적용됩니다.

import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
	button {
		padding : 5px;
    margin : 2px;
    border-radius : 5px;
	}
function App() {
	return (
		<>
			<GlobalStyle />
			<Button>전역 스타일 적용하기</Button>
		</>
	);
}

<css 코드를 Styled Components로 구현하기 연습>

/*style.css*/
* {
  margin: 0.5rem;
}

#practice {
  padding: 1rem;
  font-size: 2rem;
  background: powderblue;
  border-radius: 1rem;
  transition: 0.5s;
}

#practice:hover {
  background: cornflowerblue;
  color: white;
  transition: 0.5s;
}
//App.js
import "./styles.css";
import styled from "styled-components";=
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
	button {
	margin: 0.5rem;
  }
`;

const Button = styled.button`
	background-color: pink;
    color: white;
    border: pink;
    &:hover{  
    background-color : grey;
    color : pink;
`;

export default function App() {
  return (
		<>
			<GlobalStyle />
			<Button>Practice!</Button>
		</>
	);
}
profile
신입 프론트엔드 웹 개발자입니다.

0개의 댓글