[JavaScript] React - Styled Components 공식문서 basic 따라하기

손종일·2020년 10월 8일
0

React

목록 보기
21/22
post-thumbnail

React

Styled Components 설치 및 pakage.json에 등록

우선 CRA를 생성하고, styled-components를 설치해줍니다.

npm install --save styled-components

그리고 pakage.json에 등록하여 styled-components를 사용한다는 것을 pakage.json에 등록하여 줍니다.

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

Styled Components 공식문서 Basic 따라하기

업데이트가 자주되어 영상강의와는 다른 부분이 있기 때문에, 공식문서의 basic 부분을 따라하면서 기초를 익혀보도록 하겠습니다.

basic (Getting Started)

styled components를 적용하지 않았다면 아래의 소스처럼 js와 css를 분리해서 작성한 다음 import 하여 적용시켰을겁니다.

div {
	padding: 4em;
  background: papayawhip;
}
h1 {
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
}
<section>
  <h1>
    Hello Wolrd!
  </h1>
</section>

하지만 Styled components를 적용하여 개발하게 된다면 하기의 소스코드 처럼 변경할 수 있습니다.

// styled-components 라이브러리에서 import 해온 styled라는 객체를 이용하여
// 아래와 같이 h1 태그를 만들어 Title이라는 스타일드 컴포넌트를 생성
import React from "react";
import styled from "styled-components";

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

const Wrapper = styled.section`
  padding: 4em;
  background: papayawhip;
`;

function App() {
  return (
    <Wrapper>
      <Title>Hello Wolrd!</Title>
    </Wrapper>
  );
}

export default App;

basic (Adapting based on props)

해당 항목은 가장 기본적이면서 많이 쓰이는 항목입니다. 임포트해온 스타일드 객체를 이용하여 button tag를 만들어 Button이라는 스타일드 컴포넌트를 생성하였습니다.

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

const Button = styled.button`
  background: ${(props) => (props.primary ? "palevioletred" : "white")};
  color: ${(props) => (props.primary ? "white" : "palevioletred")};
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;
function App() {
  return (
    <div>
      <Button> Normal </Button>
      <Button primary>Primary</Button>
    </div>
  );
}

export default App;

basic (Adapting based on props)

해당 항목은 가장 기본적이면서 많이 쓰이는 항목입니다. 임포트해온 스타일드 객체를 이용하여 button tag를 만들어 Button이라는 스타일드 컴포넌트를 생성하였습니다.

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

const Button = styled.button`
  background: ${(props) => (props.primary ? "palevioletred" : "white")};
  color: ${(props) => (props.primary ? "white" : "palevioletred")};
  //Button에 primary라는 props를 주어 해당 props가 true일 경우와 false일 경우로
  // 변동되는 값으로 관리하고 있습니다.
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;
function App() {
  return (
    <div>
      <Button> Normal </Button>
      <Button primary>Primary</Button>
    </div>
  );
}

export default App;

basic (Extending Styles)

1번은 첫번째로 Button 스타일드 컴포넌트를 생성하고 똑같은 Button 스타일드 컴포넌트를 그대로 불러와 color값과 border-color값만 변경해서 사용하도록 하는 예제입니다. 이미 만들었던 스타일드 컴포넌트를 그대로 불러와 변경하고 싶은 부분만 변경해서 그대로 사용하도록 하였습니다.

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

const Button = styled.button`
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

function App() {
  return (
    <div>
      <Button> Normal Button </Button>
      <TomatoButton>Tomato Button</TomatoButton>
    </div>
  );
}

export default App;

2번은 button 태그를 as를 사용하여 a태그와 혼합한 것을 확인할 수 있습니다. 이미 태그가 지정되어 있어도 as를 사용하여 스타일을 사용하는 요소를 동적으로 변경하여 사용할 수 있습니다.

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

const Button = styled.button`
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
`;

const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

function App() {
  return (
    <div>
      <Button> Normal Button </Button>
      <Button as="a" href="/">
        Link with Button style
      </Button>
      <TomatoButton as="a" href="/">
        Link with Tomato Button styles
      </TomatoButton>
    </div>
  );
}

export default App;

3번은 props로 전달받은 값을 사용자가 원하는 내용으로 변경할 수 있습니다. 해당 예제는 전달받은 props를 분리해서 거꾸로 출력하도록 만들고 있습니다.

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

const Button = styled.button`
  display: inline-block;
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
  display: block;
`;

const ReversedButton = (props) => (
  <Button {...props} children={props.children.split("").reverse()} />
);

function App() {
  console.log(ReversedButton);
  return (
    <div>
      	<Button> Normal Button </Button>
      	<Button as={ReversedButton}>
  		Link with Normal Button styles
    	</Button>
    </div>
  );
}

export default App;

basic (Styling any component)

해당 예제에서는 Link와 Styled Link의 차이를 살펴 볼 수 있습니다. 그냥 Link 태그를 지정하고 개발자도구를 살펴보면 Link태그는 a태그로 변경되고 className이 없는것을 확인 할 수 있습니다. 하지만 StyledLink 태그에서는 className이 들어가 있는 것을 확인 할 수 있습니다.

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

const Button = styled.button`
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

const TomatoButton = styled(Button)`
  color: tomato;
  border-color: tomato;
`;

function App() {
  return (
    <div>
      <Button> Normal Button </Button>
      <TomatoButton> Tomato Button </TomatoButton>
    </div>
  );
}

export default App;

basic (Passed props)

해당 예제에서는 inputColor가 있다면 색이 바뀌고, 없다면 palevioletred가 출력되는 것을 확인 할 수 있습니다. 또한 inputColor가 아닌 비표준 속성들도 자동으로 필터링되어 적용되는 것을 확인 할 수 있습니다. Input에 value값이 없다면 defaultValue가 적용되고 type도 적용됩니다.

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

const Input = styled.input`
  padding: 0.5em;
  margin: 0.5em;
  color: ${(props) => props.inputColor || "palevioletred"};
  background: papayawhip;
  border: none;
  border-radius: 3px;
`;

function App() {
  return (
    <div>
      <Input defaultValue="@probablyup" type="text" />
      <Input defaultValue="@ge" type="text" inputColor="rebeccapurple" />
    </div>
  );
}

export default App;

basic (Coming from CSS)

해당 예제에서는 Counter 컴포넌트와 겹치지 않게 앞에 Styled만 추가하여 이름을 충돌시키지 않도록 구현하였습니다. 공식문서에서는 state로 관리하였지만 우리는 기존에 배웠던 useReducer를 적용시켜 구현해보았습니다.

import React, { useReducer, useCallback } from "react";
import styled from "styled-components";

const initialState = {
  count: 0,
};

function reducer(state, action) {
  switch (action.type) {
    case "INCREASE":
      return {
        ...state,
        count: action.count + 1,
      };
    case "DECREASE":
      return {
        ...state,
        count: action.count - 1,
      };
    case "RESET":
      return {
        ...state,
        count: 0,
      };
    default:
      throw new Error("IdontKnow");
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const { count } = state;
  const onIncrement = useCallback(() => {
    dispatch({
      type: "INCREASE",
      count,
    });
  }, [count]);

  const onDecrement = useCallback(() => {
    dispatch({
      type: "DECREASE",
      count,
    });
  }, [count]);

  const onReset = useCallback(() => {
    dispatch({
      type: "RESET",
      count,
    });
  }, [count]);

  const StyledCounter = styled.div`
    /* ... */
  `;
  const Paragraph = styled.p`
    /* ... */
  `;
  const Button = styled.button`
    /* ... */
  `;

  return (
    <StyledCounter>
      <Paragraph>{count}</Paragraph>
      <Button onClick={onIncrement}>+</Button>
      <Button onClick={onDecrement}>-</Button>
      <Button onClick={onReset}>Reset</Button>
    </StyledCounter>
  );
}

export default Counter;
profile
Allday

0개의 댓글