web-dev-qa-db-ja.com

jsxおよびReactの動的タグ名

Reactコンポーネントを記述しようとしています。 html見出しタグ(h1、h2、h3など)の場合、見出しの優先順位は、小道具で定義した優先順位に基づいて動的に変化します。

ここで私がやろうとしていること。

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

期待される出力:

<h1>Hello</h1>

これは機能していません。これを行う可能な方法はありますか?

125

その場でそれを行う方法はありません。変数に入れるだけです( 最初の文字を大文字にした ):

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

<CustomTag>Hello</CustomTag>
249
zerkms

完全を期すために、動的な名前を使用する場合は、JSXを使用する代わりに React.createElement を直接呼び出すこともできます。

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

これにより、新しい変数またはコンポーネントを作成する必要がなくなります。

小道具付き:

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

docs から:

指定されたタイプの新しいReact要素を作成して返します。 type引数は、タグ名文字列('div''span'など)、またはReactコンポーネントタイプ(クラスまたは関数)のいずれかです。

JSXで記述されたコードは、React.createElement()を使用するように変換されます。 JSXを使用している場合、通常はReact.createElement()を直接呼び出しません。詳細については React Without JSX をご覧ください。

19
Felix Kling

動的な見出し(h1、h2 ...)のインスタンスでは、コンポーネントはReact.createElement(上記の Felix で返すことができます) ) そのようです。

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

構成可能性のために、小道具と子の両方が渡されます。

例を参照

2
robstarbuck

他のすべての答えはうまく機能していますが、これを行うことで余分なものを追加します:

  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>
1
Saman Shafigh