본문 바로가기

Ecmascript/Javascript

(styled-component의 근간을 이루는) Tagged Template Literal

Template Literal의 문제점

  • 객체 타입인 경우에는 대입이 안된다
const obj = { a:1, b:2, c:3}
console.log(`${obj}`); // [object Object]
  • 함수의 경우 함수 자체가 담긴다.
var obj = () => { return { a:1, b:2, c:3} }
console.log(`${obj}`); // () => { return { a:1, b:2, c:3} }

Template Literal의 문제점 극복

  • 함수 자체가 담긴다는 성질을 이용해서 극복
  • Template Literal을 통해 만든 함수(Tagged Template Literal)는 성질이 다름
  • Tagged Template Literal의 이해
    • 첫번째 인수에는 배열로 텍스트들이 분할되서 담긴다.
    • 첫번째 인수에는 배열로 ${}의 값들이 분할되서 담긴다.
const v1 = "사과"
const v2 = "딸기"
const v3 = "포도"

function getFruits(texts, ...rest) {
    console.log(texts); // "판매량이 높은 과일은 ", ", ", ", ", "가 있습니다.", raw: Array(4)]
    console.log(rest);  // ["사과", "딸기", "포도"]
}

getFruits`판매량이 높은 과일은 ${v1}, ${v2}, ${v3}가 있습니다.`
  • Tagged Template Literal의 사용
    • 결과 데이터가 배열이므로 reduce 함수를 이용해서 ``안에 넣었던 텍스트를 리턴하는 함수를 만드는 것이 가능
function getFruits(texts, ...rest) {
    return texts.reduce((acc, cur, i) => `${acc}${cur}${rest[i] ? `${rest[i]}` : ''}`, '');
}
// "판매량이 높은 과일은 사과, 딸기, 포도가 있습니다."

getFruits`판매량이 높은 과일은 ${v1}, ${v2}, ${v3}가 있습니다.`

styled component의 원리

  • 결국 아래와 비슷한 구조여서 스타일드 컴포넌트가 작동하는 것이다.
const styled = {
    p(texts, ...rest) {
        const defaultProps = {
            color1: 'yellow',
            color2: 'orange'
        };
        return texts.reduce((acc, cur, i) => `${acc}${cur}${rest[i] ? `${rest[i](defaultProps)}` : ''}`, '');
    }
}

styled.p`
background: ${props => props.color1}
color: ${props => props.color2}
`
/*
background: yellow
color: orange
*/