스타일드 컴포넌트 HTML 요소 동적 생성

 

사내 디자인 가이드에 따라 프론트엔드 개발자 분들이 사용할 컴포넌트들을 만들고 있습니다. MUI처럼 사용할 수 있도록 여러 컴포넌트를 설계하면서 코드를 작성하고 있는데요.

 

Typography 컴포넌트 작업을 하다 HTML Element를 동적으로 변경하고 싶었는데 검색 키워드가 잘 못 됐는지 한국에서는 다루는 포스팅이 하나도 없길래 작성해 봤습니다.

 

import styled from 'styled-components'

const StyledComponent = styled.div`
    width: 100px;
    hegiht: 100px;
    border: 1px solid #000;
`

const Component = () => {

	return <StyledComponent />
}

export default Component

 

위 코드는 스타일드 컴포넌트를 사용하는 간단한 예제입니다.

const StyledComponent = styled.div``
// 위, 아래 동일
const StyledComponent = styled('div')

 

styled.div 또는 styled('div') 와 같이 HTML 태그명을 명시해 주는데, 요구사항은 원하는 태그를 Prop에 문자열로 받아서 동적으로 렌더링 할 수 있도록 코드를 작성하는 것입니다.

 

바닐라 자바스크립트에서는 document.createElement() 함수로 HTML 요소를 생성할 수 있는데요. 리액트에서도 React.createElement() 함수가 있습니다.

 

React.createElement()


React.createElement(
  type,
  [props],
  [...children]
)
  • type: HTMLElement 타입
  • props: ...props
  • children: React.Node

인자로 주어지는 타입에 따라 React 요소를 생성해 주는 함수입니다. 이 함수를 가지고 동적으로 스타일드 컴포넌트의 태그를 만들어주는 코드를 작성해 봤습니다.

 

StyledComponent.tsx


import { createElement } from 'react'
import styled from 'styled-components'

type StyledComponentTypes = {
  type: keyof JSX.IntrinsicElements
  children: React.ReactNode
}

// 스타일드 컴포넌트 요소를 동적으로 생성
const StyledComponent = styled(({ type, children, ...props }) => createElement(type, props, children))`
	display: block;
`

const StyledComponent = ({ type, variant, children }: StyledComponentTypes) => {
  return (
    <StyledComponent type={type}>
      {children}
    </StyledComponent>
  )
}

export default StyledComponent

 

만든 Styled-Component 를 사용하려면 아래 코드처럼 type에 원하는 HTML 요소 이름을 문자열로 전달하면 끝.

 

...
	<StyledComponent type="h1">
        동적으로 HTML요소 생성
	</StyledComponent>
...

 

참고


 

 

React 최상위 API – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

How to create dynamic styled component?

What I'm trying to achieve is something like this: import styled from 'react-emotion' const StyledComponent = styled(({tag}) => tag)` // some css styles ` And use it like: <StyledComp...

stackoverflow.com