조금조금 REACT, '리엑트' - TSX (3) styled-components

Edwin·2023년 6월 2일
0

조금조금 REACT

목록 보기
31/31
post-thumbnail

TSX (3) styled-components

TypeScript는 JavaScript에 대한 상위 집합 언어로 JavaScript의 단점을 보완하고 개선하기 위해 개발된 컴파일러 언어이다. TypeScript는 JavaScript의 모든 기능과 구문을 포함하면서 추가적으로 정적 타입 체크와 클래스 기반 객체 지향 프로그래밍 등을 지원한다.

JavaScript는 동적 타입 언어이기 때문에 타입 오류를 런타임 시에만 발견할 수 있는데, 이는 개발자가 코드를 실행하기 전까지는 오류를 파악하기 어렵게 만든다. TypeScript는 정적 타입 체크를 제공하여 개발자가 코드 작성 시점에서 오류를 미리 발견할 수 있도록 도와준다. 이를 통해 코드의 안정성과 가독성을 향상시킬 수 있다. TypeScript는 JavaScript의 문법을 따르기 때문에 JavaScript 코드를 거의 그대로 TypeScript로 마이그레이션할 수 있다.

CSS in TS : styled-components

CSS를 동적으로 제어하기 위해 등장한 라이브러리가 CSS in JS이고, 이는 TS에서도 사용할 수 있다. TypeScript에서 styled-components를 사용할 때는 정적 타입 체크를 활용하여 코드를 안전하게 작성할 수 있으며, styled-components는 내부적으로 TypeScript를 지원한다. 즉 스타일에 사용되는 속성 및 값에 대한 타입을 설정할 수 있다. 이를 통해 스타일 관련 오류를 컴파일 시간에 미리 확인할 수 있다.

yarn add styled-components
yarn add @types/styled-components

터미널에서 라이브러리를 설치할 때, styled-components에서 지원하는 타입을 선언해 주면 된다.

GlobalStyled = createGlobalStyle<GlobalStyledProps>

import React, { useState } from 'react'
import GlobalStyled from './global'


const App:React.FC =() => {
  const [mouseHover, setMouseHover] =  useState<boolean>(false)
  
  return (
    <>
    <GlobalStyled info={mouseHover}/>
	...
    </>
  )
}

export default App

리액트에서 CSS in JS를 사용할 때의 이점은 props를 통하여 조건부 스타일 설정을 지원한다는 점이다. 이는 styled 메서드를 통해서 각 컴포넌트를 직접 스타일링하고 제어할 수 있다. 또한 createGlobalStyle을 선언하여 광범위한 범위의 스타일을 제어할 수 있다. 보통의 경우에서는 각 컴포넌트 단위를 제어하기 때문에 고민할 이유가 없었겠지만, 초기 설정을 위해 createGlobalStyle에서 스타일을 제어하다 보니, Type 설정의 문제가 발생했다. createGlobalStyle에 설정된 기존의 Type를 직접수정해야, 동적제어가 가능하다.

ThemedStyledProps 설정하기

먼저, 별도의 파일( global.ts )을 생성하고 아래의 코드를 기록하였다.

import { ThemedStyledProps, CSSObject } from 'styled-components';

// ThemedGlobalStyledClassProps 정의
export type ThemedGlobalStyledClassProps<P, T> = {
  as?: React.ElementType;
  forwardedAs?: React.ElementType;
  css?: CSSObject | CSSObject[];
} & ThemedStyledProps<P, T>;

// GlobalStyledProps 정의
export type GlobalStyledProps = {
  info: boolean;
};

둘째, 분리한 GlobalStyled 파일( global.tsx )에 Type을 적용해준다. global.ts에서 볼 수 있듯이 props 에 대한 Type을 제너릭으로 설정하였고, 이를 적용하기 위해 global.tsx에 제너릭으로 Type을 추가하였다. 이를 통해서 useState에서 관리하는 리소스의 진위값에 따라 조건부 스타일을 제어하였다.

// 1분코딩의 3D-Card 유튜브 강의를 참고하였습니다. 
import {createGlobalStyle} from 'styled-components';
import { GlobalStyledProps } from './types/global';

const GlobalStyled = createGlobalStyle<GlobalStyledProps>`
	
	...
	    @keyframes poster-ani {
      // from
      0% {
        transform: rotateY(-20deg);
      }
      // to
      100% {
        transform: rotateY(20deg);
      }
	...
	.poster {
      animation: ${props => props.info ? "poster-ani 2s infinite linear alternate" : "none"};
      transform-style: ${props => props.info ? "preserve-3d" : "none"};
    }
`

  • 모바일(iPhone12Pro 짧은 가로) : 조건부 없이 3DCard가 무한반복되며 왔다갔다 하도록 설정했다.
  • 모바일(iPhone12Pro 긴 가로) : 조건부 없이 3DCard가 무한반복되며 왔다갔다 하도록 설정했다.
  • 테블릿(iPad Air 짧은 가로) : 조건부 없이 3DCard가 무한반복되며 왔다갔다 하도록 설정했다.
  • 테블릿(iPad Air 긴 가로) : onMouse 이벤트에 따라 3DCard가 조건부로 무한반복되며 왔다갔다 하도록 설정했다.
  • 데스크탑(850px 이하) : 조건부 없이 3DCard가 무한반복되며 왔다갔다 하도록 설정했다.
  • 데스크탑(850px 이상) : onMouse 이벤트에 따라 3DCard가 조건부로 무한반복되며 왔다갔다 하도록 설정했다.

테블릿의 경우에는 마우스 이벤트가 Click 이벤트로 설정되는 것 같다. 호버한다고 동작하는 것이 아니라 마우스 포인터로 클릭할 때 동작되었기 때문이다. 반면에 데스크탑에서는 원하는데로 정상 작동하였다.

컴포넌트 분리와 styled 메서드에 대한 props Type 설정하기

기존의 하나로 구성했던 코드들을 분활하였다. App 태그에 Router를 적용하였고, Home.tsx를 따로 구성하였다. 그 결과 GlobalStyled에 Type을 적용하지 않아도 되게 되었다. 이를 위해 아래와 같이 styled 메서드에 대한 Type 설정을 지정하였다.

큰 변경 없이 기존에 있엇던 코드를 약간 수정하였다.

export type HomePropsType = {
  info: boolean;
};

HomePropsType 을 별도의 파일에 생성하고, 이를 분리한 컴포넌트에 적용해주었다.

import { HomePropsType } from '../libs/types/global';
const Home: React.FC = () => {

  return (
    <HomeLayoyt info={mouseHover}>
    </HomeLayoyt>
  )
}

export default Home;

const HomeLayoyt = styled.div<HomePropsType>`
  ...

`

Author. Edwin
Date. 23/06/02

profile
신학전공자의 개발자 도전기!!

0개의 댓글