jsx 및 React의 동적 태그 이름


163

React 구성 요소를 작성하려고합니다. html 제목 태그 (h1, h2, h3 등)의 경우, 제목 우선 순위는 소품에서 정의한 우선 순위에 따라 동적으로 변경됩니다.

여기 내가하려는 일.

<h{this.props.priority}>Hello</h{this.props.priority}>

예상 출력 :

<h1>Hello</h1>

작동하지 않습니다. 가능한 방법이 있습니까?


답변:


329

그 자리에서 그렇게 할 수있는 방법이 아니라 변수에 넣으십시오 ( 첫 글자는 대문자로 표시 ).

const CustomTag = `h${this.props.priority}`;

<CustomTag>Hello</CustomTag>

5
보다 확실히 React.createClass, 나는이 방법을 선호합니다. 감사.
Vadorequest

@zerkms CustomTag에 속성을 추가하는 방법에 대해 알고 있습니까? 감사
사브리나 루오

1
@Sabrina<CustomTag foo="bar">
zerkms

허. 어떻게 작동합니까? 변수 이름이 소문자이면 해당 태그를 태그로 삽입합니다 (예 : customtag 인 경우 <customtag> Hello </ customtag>가 표시됨). 이것은 어디에나 문서화되어 있습니까?
이브라힘

5
구성 요소가 객체의 속성에 저장된 경우 대문자 첫 글자는 필요하지 않습니다. var foo = { bar: CustomTag }; return <foo.bar />잘 작동합니다.
jdunning

29

완전성을 위해 동적 이름을 사용하려는 경우 React.createElementJSX를 사용하는 대신 직접 호출 할 수도 있습니다 .

React.createElement(`h${this.props.priority}`, null, 'Hello')

이렇게하면 새 변수 나 구성 요소를 작성하지 않아도됩니다.

소품으로 :

React.createElement(
  `h${this.props.priority}`,
  {
    foo: 'bar',
  },
  'Hello'
)

로부터 문서 :

주어진 유형의 새로운 React 요소를 생성하고 반환합니다. type 인수는 태그 이름 문자열 (예 : 'div'또는 'span') 또는 React 구성 요소 유형 (클래스 또는 함수) 일 수 있습니다.

JSX로 작성된 코드는를 사용하도록 변환됩니다 React.createElement(). React.createElement()JSX를 사용하는 경우 일반적으로 직접 호출하지 않습니다 . 자세한 내용은 JSX없이 반응을 참조하십시오 .


11

TypeScript를 사용하는 경우 다음과 같은 오류가 표시됩니다.

Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.ts(2559)

TypeScript CustomTag는 이것이 유효한 HTML 태그 이름이며 알 수없는 오류를 발생시킵니다.

해결하려면 캐스트 CustomTagkeyof JSX.IntrinsicElements!

const CustomTag = `h${this.props.priority}` as keyof JSX.IntrinsicElements;

<CustomTag>Hello</CustomTag>

TypeScript를 사용하고 있지만 캐스팅하면 다음과 같은 오류가 발생합니다.Types of property 'crossOrigin' are incompatible. Type 'string | undefined' is not assignable to type '"" | "anonymous" | "use-credentials" | undefined'. Type 'string' is not assignable to type '"" | "anonymous" | "use-credentials" | undefined'.
Can Poyrazoğlu

8

다른 모든 답변은 잘 작동하지만 추가로 추가 할 것입니다.

  1. 조금 더 안전합니다. 형식 검사에 실패하더라도 여전히 올바른 구성 요소를 반환합니다.
  2. 더 선언적입니다. 이 구성 요소를 보면 누구나 반환 할 수있는 것을 볼 수 있습니다.
  3. 예를 들어 'h1', 'h2'대신에 더 유연합니다. 제목 유형의 경우 다른 추상 개념 'sm', 'lg'또는 'primary', 'secondary'를 가질 수 있습니다.

제목 구성 요소 :

import React from 'react';

const elements = {
  h1: 'h1',
  h2: 'h2',
  h3: 'h3',
  h4: 'h4',
  h5: 'h5',
  h6: 'h6',
};

function Heading({ type, children, ...props }) {    
  return React.createElement(
    elements[type] || elements.h1, 
    props, 
    children
  );
}

Heading.defaultProps = {
  type: 'h1',
};

export default Heading;

당신이 그것을 사용할 수있는

<Heading type="h1">Some Heading</Heading>

또는 다른 추상 개념을 가질 수 있습니다. 예를 들어 다음과 같은 크기 소품을 정의 할 수 있습니다.

import React from 'react';

const elements = {
  xl: 'h1',
  lg: 'h2',
  rg: 'h3',
  sm: 'h4',
  xs: 'h5',
  xxs: 'h6',
};

function Heading({ size, children }) {
  return React.createElement(
    elements[size] || elements.rg, 
    props, 
    children
  );
}

Heading.defaultProps = {
  size: 'rg',
};

export default Heading;

당신이 그것을 사용할 수있는

<Heading size="sm">Some Heading</Heading>

2

동적 제목 (h1, h2 ...) 의 경우 구성 요소가 React.createElement( Felix에서 언급 한 것처럼) 반환 될 수 있습니다.

const Heading = ({level, children, ...props}) => {
    return React.createElement(`h${level}`, props , children)
}

작곡가를 위해 소품과 어린이가 모두 전달됩니다.

예 참조

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.