styled-components의 이상한 문법
styled-components 또는 Emotion을 사용하는 사람들은 다음과 같은 코드가 매우 익숙할 것이다.
const Button = styled.a`
display: inline-block;
border-radius: 3px;
padding: 0.5rem 0;
margin: 0.5rem 1rem;
width: 11rem;
background: transparent;
color: white;
border: 2px solid white;
`
예시 코드에 적혀 있어서, 강의에서 이렇게 하라고 해서 지금껏 사용해오긴 했는데... 이게 대체 무슨 문법일까? styled-components에서만 사용되는 구문이라고 생각할 수 있겠지만, 이건 Tagged Templates라고 불리는 자바스크립트 함수 호출 방법으로, 흔히 문자열을 다룰 때 사용하는 Template Literals의 발전된 사용 방법이다.
왜 사용할까?
그럼 일반적인 방법을 놔두고 왜 이런 이상한 형식으로 함수를 호출하는 걸까?
먼저, Tagged Templates를 사용하면 함수를 작성할 때, 문자열의 리터럴과 변수를 파싱 하기가 매우 쉬워진다. 또, 개인적인 생각이지만, 함수를 사용하는 입장에서도 별도의 매개변수에 값을 담지 않고, 자연스러운 순서로 적을 수 있기 때문에 편리한 것 같다. 만약 Tagged Templates 없이 styled-components의 함수들을 호출하려면 매우 끔찍할 것이다.
뿐만 아니라 Tagged Templates는 일반적인 함수 호출은 하지 못하는 일을 할 수 있다. Template Literals에 담긴 객체를 그대로 받을 수 있는데, 일반적인 방식으로 호출하면 [obejct Object]
와 같이 출력된다
function consolelog(text, obj) {
console.log(obj);
}
const obj = {name: '슥짱'}
consolelog`${obj}`; //{name: '슥짱'}
consolelog('', `${obj}`); //[object Object]
함수를 넘겨받는 것도 가능하다. styled-components에서 컴포넌트의 props를 받아올 때 흔히 아래와 같이 작성하는데, 여기서${props => props.color}
가 바로 props의 속성 color를 리턴하는 함수였던 것이다.
const Buntton = styled.button`
height: 2rem;
font-size: 1rem;
color: ${props => props.color};
background: ${props= > props.background};
`
사용 방법
Tagged Templates으로 함수를 호출하기 위해서는 함수명`문자열 ${변수}`
형식으로 작성한다. 문자열은 표현식(${}
)를 기준으로 split 되어 첫 번째 인수에 배열 형태로 담긴다. 두 번째 이하의 인수는 표현식에 담긴 값을 순서대로 받는다. 출력 결과를 확인해보면 금방 이해가 될 것이다.
function myInfo(strings, name, age){
console.log(strings) // ['My name is ', " I'm ", ' years old', raw: Array(3)]
console.log(name) // 슥짱
console.log(age) // 25
}
myInfo`My name is ${'슥짱'} I'm ${25} years old`
일반적인 방식으로 함수를 호출하면 두 번째 이후의 인자는 받지 못하기 때문에 주의해야 한다.
myInfo(`My name is ${'슥짱'} I'm ${25} years old`) //My name is 슥짱 I'm 25 years old undefined undefined
참고 자료
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals
- https://react.vlpt.us/styling/03-styled-components.html
'Javascript' 카테고리의 다른 글
[Javascript] 변수 선언과 호이스팅(feat. TDZ) (2) | 2022.12.27 |
---|---|
[Javascript] 리덕스 만들어보기 - (1) (0) | 2022.07.24 |
[Javascript] this: 이름 값 못하는 자바스크립트의 this (0) | 2022.07.03 |
[Javascript] requestAnimationFrame(애니메이션 최적화하기) (0) | 2022.04.25 |
[Javascript] Closure (0) | 2022.04.14 |
댓글