본문 바로가기
REACT

React Challenge Day 1 | STYLED COMPONENTS

by 승행 2022. 1. 24.

#2.1 styled components

creact-react-app, styled component 설치 및 셋팅

npx create-react-app react-challenge

기존 css로 작성한 것과 style component로 작성한 코드의 차이 경험

styled-component는 각각 컴포넌트로 만들어서 사용함

코드가 간결하고 재활용에 용이, 가독성 좋음

` ` 백틱 사용

 

 

#2.2 Adapting and Extending

중복되는 값을 제거하고 컴포넌트를 설정 변경 가능한 형태로 만들기

컴포넌트 확장

// 변경 전
const BoxOne = styled.div`
  background-color: teal;
  width: 100px;
  height: 100px;
`;

const BoxTwo = styled.div`
  background-color: tomato;
  width: 100px;
  height: 100px;
`;
// props를 이용해 컴포넌트의 설정을 변경할 수 있게
const Box = styled.div`
  background-color: ${(props) => props.bgColor};
  width: 100px;
  height: 100px;
`;

function App() {
  return (
    <Father>
      <Box bgColor="teal"></Box>
      <Box bgColor="tomato"></Box>
    </Father>
  );
}
// 확장
// Circle에 Box의 property를 코드 중복 없이 가져옴
// Box의 모든 property를 가져온 후 Circle의 property 추가

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

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

function App() {
  return (
    <Father>
      <Box bgColor="teal"></Box>
      {/* Circle에서도 bgColor 변경 가능 */}
      <Circle bgColor="tomato"></Circle> 
    </Father>
  );
}

컴포넌트 확장의 의미는 다른 컴포넌트의 속성을 그대로 가져와 자신의 속성을 추가하는 것

이 때, 코드 중복 발생 x

 

App()에서 설정한 prop의 이름과 컴포넌트에서 사용하는 props의 이름은 같아야 함

 

 

#2.3 'As' and Attrs

다수의 컴포넌트를 다룰 때 도움이 될만한 트릭

 

1. 'as'

컴포넌트의 태그를 바꾸고 싶은데 스타일은 바꾸고 싶지 않을 때

뭔가를 추가할 계획이 없어서 컴포넌트를 확장하고 싶지 않을 때

ex) button 태그를 사용했으나 a 태그처럼 사용하고 싶을 때 ----> 'as'

// element에서도 <a>로 바뀜

// button -> a
const Btn = styled.button`
  color: white;
  background-color: tomato;
  border: 0;
  border-radius: 15px;
`;

function App() {
  return (
    <Father>
      <Btn>Log in</Btn>
      {/* as="a" 사용*/}
      <Btn as="a" href="/">
        Log in
      </Btn>
    </Father>
  );
}
// div -> header
function App() {
  return (
    <Father as="header">
      <Btn>Log in</Btn>
      <Btn as="a" href="/">
        Log in
      </Btn>
    </Father>
  );
}

2. '.attrs'

styled components가 컴포넌트를 생성할 때, 속성값을 설정할 수 있게 해줌

tagName.attrs({})에는 해당 태그의 모든 속성을 가진 오브젝트를 담을 수 있음

 

만약 form이 있고 input이 많으면 하나하나 required라고 적어줘야함

const Input = styled.input.attrs({ required: true, minLength: 10 })`
  background-color: tomato;
`;

function App() {
  return (
    <Father as="header">
      <Input />
      <Input />
      <Input />
      <Input />
      <Input />
    </Father>
  );
}

 

 

#2.4 Animations and Pseudo Selectors

> Animations

styled component 에서의 animation

helper function을 import해서 사용

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

Box 밖에서 animation 컴포넌트 생성

기존 css와 비슷하지만 javascript의 string interpolation을 사용함

const rotationAnimation = keyframes`
/* from{}to{} */
  0% {
    transform:rotate(0deg);
    border-radius: 0px;
  }
  50% {
    border-radius: 100px;
  }
  100%{
    transform:rotate(360deg);
    border-radius: 0px;
  }
`;

const Box = styled.div`
  height: 200px;
  width: 200px;
  background-color: tomato;
  animation: ${rotationAnimation} 1s linear infinite;
`;

function App() {
  return (
    <Wrapper>
      <Box></Box>
    </Wrapper>
  );
}

 

> Pseudo Selectors

component에서 사용할 수 있는 selector

꼭 모든 component에 styled component 처리를 해 줄 필요는 없고 아래와 같은 방법을 사용해도 됨

 

Box 안에 있는 span 속 이모지를 선택

const Box = styled.div`
  height: 200px;
  width: 200px;
  background-color: tomato;
  display: flex;
  justify-content: center;
  align-items: center;
  animation: ${rotationAnimation} 1s linear infinite;
  
  /* Box 안에 있는 span 속 이모지를 선택 */
  span {
    font-size: 36px;
    &:hover {
      font-size: 60px;
    }
    &:active {
      opacity: 0;
    }
  }
`;

function App() {
  return (
    <Wrapper>
      <Box>
        <span>🎅</span>
      </Box>
    </Wrapper>
  );
}

 

 

#2.5 Pseudo Selectors

styled component 안의 element를 선택하는 다른 방법

tag name에 의존하고 있다면 태그명을 바꿨을 경우(span->p) 효과가 적용되지 않음

 

태그명에 의존하고 싶지 않다면? 

-> 우리만의 styled component를 만들면 됨

 

Box 컴포넌트 안에 Emoji 컴포넌트를 직접적으로 타겟팅

-> 이러면 Emoji가 div든 span이든 p든 상관 없음

const Emoji = styled.span`
  font-size: 36px;
`;

const Box = styled.div`
  height: 200px;
  width: 200px;
  background-color: tomato;
  display: flex;
  justify-content: center;
  align-items: center;
  animation: ${rotationAnimation} 1s linear infinite;
  ${Emoji} {
    &:hover {
      font-size: 60px;
    }
    &:active {
      opacity: 0;
    }
  }
`;

function App() {
  return (
    <Wrapper>
      <Box>
        <Emoji>🎅</Emoji>
      </Box>
    </Wrapper>
  );
}

 

 

#2.7 Themes

Theme: 모든 색상들을 가지고 있는 하나의 object

-> component의 색깔을 일일이 바꿔주지 않고 object 하나의 색만 바꿔줘도 돼서 편리함

 

먼저, index.js에서 ThemeProvider 라는 걸 styled-components로부터 import 해줘야 함 

import { ThemeProvider } from "styled-components";

ThemeProvider을 theme이라는 prop이 하나 필요함

 

// index.js

import React from "react";
import ReactDOM from "react-dom";
// import ThemeProvider
import { ThemeProvider } from "styled-components";
import App from "./App";

// 모드별로 컴포넌트를 만들어서 ThemeProvider의 prop인 theme으로 사용하면
// prop 하나만 변경해도 전체 색 변경 가능
const darkTheme = {
  textColor: "whitesmoke",
  backgroundColor: "black",
};

const lightTheme = {
  textColor: "#11111",
  backgroundColor: "black",
};

ReactDOM.render(
  <React.StrictMode>
    {/* ThemeProvider로 App을 감싸서 App 전체에 theme을 적용 */}
    <ThemeProvider theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

 

// App.js

import styled from "styled-components";

const Title = styled.h1`
  /* index에서 지정한 컴포넌트 내부 속성명을 불러와 prop 변경 */
  /* textColor 변경 */
  color: ${(props) => props.theme.textColor};
`;

const Wrapper = styled.div`
  display: flex;
  height: 100vh;
  width: 100vw;
  justify-content: center;
  align-items: center;
  /* backgroundColor 변경 */
  background-color: ${(props) => props.theme.backgroundColor};
`;

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

export default App;

property 몇 개를 가진 object를 ThemeProvider에 전달하기만 하면 끝

그럼 ThemeProvider 안에 있는 모든 component들은 이 object에 접근할 수 있게 됨

반전해서 사용할 property의 이름은 꼭 같아야 함!

ex) textColor, backgroundColor

'REACT' 카테고리의 다른 글

강의 내용 정리 (기초)  (1) 2022.11.18
React에서 레이아웃 만들 때 쓰는 JSX 문법 3가지  (0) 2022.11.08
React를 사용하는 이유  (0) 2022.11.08
# 3. State  (0) 2021.10.10