본문 바로가기

FrontEnd

[React][CSS] css를 styled-component로 변환하기

반응형

해당 게시물은 https://velog.io/@hyeoki/React-css%EB%A5%BC-styled-component%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0 에서도 볼 수 있다.

Styled Component의 장점

  1. class nesting이 필요 없음.
    • &(parent selector)로 자기 스타일은 자기가 책임진다.
  2. 더 명확한 이름
  3. 스타일 충돌(및 클래스명 충돌) 걱정 및 벤더프리픽스 걱정을 안해도 됨.
    • 이건 명시적이진 않음.
  4. className(class)속성을 사용하지 않음.
    • 이건 tailwind같은 프레임워크를 사용하면서도 점차 나타나는 현상.5. 더 나은 개발 경험

예제

아래 프로젝트는 디테일(html의 신기한 기능), 폼, 아바타 카드를 styled-component로 변경한 예제이다.
before 폴더에는 이전 소스가, after 폴더에는 styled-component로 변경된 소스가 들어있다.

나머지는 간단하니 가장 복잡한 인터랙션이 들어가 있는 폼을 설명하겠다.

폼 컴포넌트 설명

눈여겨볼 점은 컴포넌트 변수명의 표현력이다.

컨벤션으로 최상위 엘리먼트는 Wrapper로 네이밍한다.

const Wrapper = styled.form`
  width: max-content;
  margin: 16px auto;
  border: 1px dotted silver;
  padding: 26px 32px 32px;
  border-radius: 2px;
`;

Label은 특별히 다형성이 없으므로 Label로 네이밍 하였다.

const Label = styled.label`
  display: block;
  margin-bottom: 16px;
`;

input은 Radio, Submit도 될 수 있기 때문에 좀 더 적절한 이름을 부여한다.
input이라는 이름이 인터페이스라면, 변수명은 클래스다.
또한, 자기 자신에대한 포커싱을 &(parent selector)로 자기 자신이 처리하고 있다.
이건 encapsulation의 한 종류라 할 수 있겠다.

const TextInput = styled.input`
  display: block;
  width: 175px;
  border: 1px solid black;
  border-bottom-width: 2px;
  padding: 6px 8px;
  margin-top: 4px;
  border-radius: 2px 2px 3px 3px;
  &:focus {
    outline: 3px auto blue;
    outline-offset: 2px;
    border-color: transparent;
  }
`;

버튼도 다양한 역할(submit,reset,modal open)을 할 수 있기 때문에 명확한 역할을 보여주는 이름을 사용한다.
자기 자신에대한 포커싱을 &(parent selector)로 자기 자신이 처리하고 있다.

const SubmitButton = styled.button`
  display: block;
  margin-top: 40px;
  width: 100%;
  background: black;
  color: white;
  padding: 8px;
  border: none;
  font-size: 1rem;
  font-weight: 600;
  text-transform: uppercase;
  border-radius: 3px;
  &:focus {
    outline: 3px auto blue;
    background: blue;
    outline-offset: 2px;
  }
`;

최종 컴포넌트는 다음과 같다.

export default function LoginForm({
  handleSubmit
}: {
  handleSubmit: (event: React.FormEvent<LoginFormElement>) => void;
}) {
  return (
    <Wrapper id="login-form" onSubmit={handleSubmit}>
      <Label>
        Email:
        <TextInput id="email" type="email" placeholder="me@you.com" />
      </Label>
      <Label>
        Password:
        <TextInput id="password" type="password" />
      </Label>
      <SubmitButton type="submit">Log In</SubmitButton>
    </Wrapper>
  );
}

다른 예제들도 보고싶다면 codesandbox를 열어보자.

반응형