web-dev-qa-db-fra.com

Nom de tag dynamique dans jsx et React

J'essaie d'écrire un composant React. pour les balises de titre html (h1, h2, h3, etc ...), où la priorité de titre change de manière dynamique en fonction de la priorité que nous avons définie dans les accessoires.

Voici ce que j'essaie de faire.

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

production attendue:

<h1>Hello</h1>

Ceci ne fonctionne pas. Y at-il une méthode possible pour faire cela?

130

Aucun moyen de le faire sur place, il suffit de le mettre dans une variable ( avec la première lettre en majuscule ):

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

<CustomTag>Hello</CustomTag>
261
zerkms

Pour être complet, si vous souhaitez utiliser un nom dynamique, vous pouvez également appeler directement React.createElement au lieu d'utiliser JSX:

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

Cela évite de créer une nouvelle variable ou un nouveau composant.

Avec des accessoires:

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

De la docs :

Créez et retournez un nouvel élément React du type donné. L'argument de type peut être une chaîne de nom de balise (telle que _'div'_ ou _'span'_) ou un type de composant React (une classe ou une fonction).

Le code écrit avec JSX sera converti pour utiliser React.createElement(). Si vous utilisez JSX, vous n’appellerez généralement pas directement React.createElement(). Voir React Without JSX pour en savoir plus.

20
Felix Kling

Toutes les autres réponses fonctionnent bien, mais je voudrais ajouter un peu plus, car en faisant cela:

  1. C'est un peu plus sûr. Même si votre vérification de type échoue, vous retournez toujours un composant approprié.
  2. C'est plus déclaratif. Quiconque regarde ce composant peut voir ce qu’il pourrait retourner.
  3. Il est plus flexible, par exemple, au lieu de "h1", "h2", ... pour le type de votre en-tête, vous pouvez avoir d'autres concepts abstraits "sm", "lg" ou "primaire", "secondaire".

Le composant Heading:

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 vous pouvez utiliser comme

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

ou vous pouvez avoir un concept abstrait différent, par exemple vous pouvez définir une taille d'accessoire comme:

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 vous pouvez utiliser comme

<Heading size="sm">Some Heading</Heading>
3
Saman Shafigh

Dans le cas des en-têtes dynamiques (h1, h2 ...) , un composant pourrait renvoyer React.createElement (mentionné ci-dessus par Félix ) comme ça.

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

Pour la composabilité, les accessoires et les enfants sont passés.

voir exemple

2
robstarbuck