Emotion(Styled), Props 전달하기(Typescript)

Typescript와 함께 동적 CSS 스타일 사용하기
import styled from "@emotion/styled";

const StyledPropsTest = styled.div`
  width: 120px;
  height: 40px;
  font-size: 25px;
  background: ${(props) => (props.testProps ? "blue" : "red")};
  color: white;
`;

const StyledTest = ({testprops}) => {
  return(
    <StyledPropsTest testProps={testprops}>Prop Test</StyledPropsTest>
  )
}

export default StyledTest;

컴포넌트 내부에서 사용하는 변수를 CSS에 전달하여 동적 스타일을 적용하기 위해서는 위와 같이 props를 전달하는 방법이 있습니다.

하지만 Typescipt를 사용하여 custom props를 사용하면 다음과 같은 에러를 만나게 됩니다.

(property) testProps: boolean
Type ‘{ children: string; testProps: boolean; }’ is not assignable to type ‘IntrinsicAttributes & { theme?: Theme | undefined; as?: ElementType<any> | undefined; } & ClassAttributes<HTMLDivElement> & HTMLAttributes<…>’.
Property ‘testProps’ does not exist on type ‘IntrinsicAttributes & { theme?: Theme | undefined; as?: ElementType<any> | undefined; } & ClassAttributes<HTMLDivElement> & HTMLAttributes<…>’.ts(2322)

이는 타입스크립트에서 props의 타입을 체크하기 때문인데요.

다음과 같이 간단하게 <{data:type}>의 타입 단언(Type Assertion)으로 해결할 수 있습니다.

const StyledPropsTest = styled.div<{testProps:boolean}>`
  width: 120px;
  height: 40px;
  font-size: 25px;
  background: ${(props) => (props.testProps ? "blue" : "red")};
  color: white;
`;

다음과 같이 에러가 사라진 것을 확인할 수 있습니다.

템플릿 리터럴(template literal)과 쉬운 응용(feat.`)

`로 시작해서 `로 끝나는 템플릿 리터럴

템플릿 리터럴(template literal)은 ES6부터 도입된 기능으로 문자열 다루기에 특화된 기능인데요.

` (backtick, grave accent)

템플릿 리터럴은 ` 기호로 시작해 ` 기호로 끝나며, 문자열과 변수를 함께 전달하거나 태그를 편리하게 사용할 수 있습니다.

또한 다음과 같은 방식도 사용도 가능한데요.

const printData = (text) => {
    console.log(text[0]); // 'Hello everyone!'
}

printData`Hello everyone!`;

함수에 템플릿 리터럴을 전달할 수도 있습니다.

이를 태그드 템플릿(tagged template)이라고 하는데요.

호출된 함수는 템플릿 리터널 내 문자열 조각이나 표현식 등을 매개변수로 받습니다.

styled-components에서 사용되는 방식도 태그드 템플릿입니다.


1. 템플릿 리터럴(template literal)

템플릿 리터럴은 시작과 끝에 반드시 `(backtick)을 붙여야 하며, ‘(홑따옴표), “(쌍따옴표)와 반드시 구분해야 합니다.

const name = 'clint Eastwood';
const age = '92';
const city = 'San Francisco';
const occupation = 'director';

// 표현식
console.log('His name is '+name+ '\n' + 'and '+age+'.');

// 템플릿 리터럴
console.log(`He was born in ${city}
and he is a ${occupation}`);

템플릿 리터럴에서 ${ }를 사용하면 블록 내 변수 또는 함수에 접근이 가능하며, \n 등 이스케이프를 사용하지 않고도 입력한대로 출력할 수 있습니다.

템플릿 리터럴은 쉽게 응용이 가능하니 태그드 템플릿에 대해 알아보겠습니다.

2. 태그드 템플릿(tagged template)

const TextBox = styled.div`
  display: inline-block;
  color: gray;
  margin: 0 auto;
`;

const StyledInput = styled.input`
    font-size: 1rem;
    border: none;
    border-bottom: 1px solid gray;
    outline: none;
    width: 100%;
`;

위와 같이 styled-components에서 태그드 템플릿이 밥 먹듯이 사용됩니다.

템플릿 리터럴로 함수를 호출하면 어떻게 사용할까요?

함수를 호출하면 매개변수로 문자열과 변수가 전달됩니다.

const name = 'clint';
const age = '92';
const city = 'LA';

const showString = (text, ...args) => {
    console.log(text);
    console.log(args);
    console.log(text[2]);
    console.log(args[2]);
}

showString`He is ${name} and ${age}. From ${city}`;

전달된 매개변수는 텍스트와 ${ }에 넣은 변수이며, 각각 확인할 수 있습니다.

텍스트와 변수에 접근하려면 인덱스를 사용하면 됩니다.

텍스트의 경우 ${ }이 들어간 부분에서 끊어주므로 ‘He is’, ‘ and ‘, ‘. From ‘, ”이렇게 네 부분으로 나뉘어지며, 순서대로 0, 1, 2, 3의 인덱스를 갖습니다.

태그드 템플릿을 사용하는 이유는 문자열을 원하는 형식으로 재가공하여 사용할 수 있는 장점이 있기 때문입니다.



styled-components를 무턱대고 사용하는 것보다 구조를 알고 사용하면 더 도움이 될 것 같아 태그드 리터럴에 대해 알아보았습니다. 템플릿 리터럴은 이제 너무 유용하고 편리한 기능이므로 꼭 알아두어야 할 기능 중 하나인 것 같습니다.