Nome da tag dinâmica em jsx e React


162

Eu tento escrever um componente React. para tags de cabeçalho html (h1, h2, h3, etc ...), em que a prioridade do cabeçalho muda dinamicamente com base na prioridade que definimos nos adereços.

Aqui o que eu tento fazer.

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

resultado esperado:

<h1>Hello</h1>

Isto não está a funcionar. Existe algum método possível para fazer isso?


Respostas:


328

Não há como fazer isso no local, basta colocá-lo em uma variável ( com a primeira letra maiúscula ):

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

<CustomTag>Hello</CustomTag>

5
Definitivamente mais fácil do que React.createClasseu prefiro assim. Obrigado.
Vadorequest

@zerkms Você tem alguma idéia de como adicionar atributos à CustomTag? obrigado
Sabrina Luo

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

Hã. Como é que isso funciona? Se o nome da variável estiver em letras minúsculas, ele será inserido apenas como uma tag (por exemplo, se fosse o rótulo da região, eu receberia <customtag> Olá </customtag>). Isso está documentado em algum lugar?
Ibrahim

5
Se o componente estiver armazenado na propriedade de um objeto, uma primeira letra maiúscula não será necessária. var foo = { bar: CustomTag }; return <foo.bar />funciona bem.
Jdunning

29

Para React.createElementgarantir a integridade, se você quiser usar um nome dinâmico, também poderá ligar diretamente em vez de usar JSX:

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

Isso evita a necessidade de criar uma nova variável ou componente.

Com adereços:

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

Dos documentos :

Crie e retorne um novo elemento React do tipo especificado. O argumento type pode ser uma string de nome de tag (como 'div'or 'span') ou um tipo de componente React (uma classe ou uma função).

O código escrito com JSX será convertido para uso React.createElement(). Você normalmente não invocará React.createElement()diretamente se estiver usando JSX. Consulte Reagir sem JSX para saber mais.


11

Se você estiver usando o TypeScript, verá um erro como este:

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

O TypeScript não sabe que CustomTagé um nome de marca HTML válido e gera um erro inútil.

Para consertar, use CustomTagcomo keyof JSX.IntrinsicElements!

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

<CustomTag>Hello</CustomTag>

Estou no TypeScript, mas a transmissão dá o seguinte erro: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'.
Poyrazoğlu

8

Todas as outras respostas estão funcionando bem, mas gostaria de acrescentar algumas extras, pois, ao fazer isso:

  1. É um pouco mais seguro. Mesmo se sua verificação de tipo estiver falhando, você ainda retornará um componente adequado.
  2. É mais declarativo. Qualquer pessoa olhando para este componente pode ver o que ele poderia retornar.
  3. É mais flexível, por exemplo, em vez de 'h1', 'h2', ... para o tipo de cabeçalho, você pode ter outros conceitos abstratos 'sm', 'lg' ou 'primário', 'secundário'

O componente Título:

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;

Que você pode usar como

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

ou você pode ter um conceito abstrato diferente, por exemplo, pode definir adereços de tamanho como:

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;

Que você pode usar como

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

2

No caso de títulos dinâmicos (h1, h2 ...) , um componente pode retornar React.createElement(mencionado acima por Felix ) assim.

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

Para composição, adereços e filhos são aprovados.

Consultar exemplo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.