Jsx ve React içindeki dinamik etiket adı


163

Bir React bileşeni yazmaya çalışıyorum. html başlık etiketleri (h1, h2, h3, vb ...) için, burada başlık önceliği, aksesuarlarda tanımladığımız önceliğe göre dinamik olarak değişir.

İşte yapmaya çalıştığım şey.

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

beklenen çıktı:

<h1>Hello</h1>

Bu çalışmıyor. Bunu yapmak için olası bir yöntem var mı?


Yanıtlar:


329

Bunu yerinde yapmanın bir yolu yok, sadece bir değişkene koyun ( ilk harf büyük yazılır ):

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

<CustomTag>Hello</CustomTag>

5
Kesinlikle daha kolay React.createClass, bu yolu tercih ederim. Teşekkürler.
Vadorequest

@zerkms CustomTag'e özelliklerin nasıl ekleneceği hakkında bir fikriniz var mı? teşekkürler
Sabrina Luo

1
Sabrina<CustomTag foo="bar">
zerkms

Huh. Bu nasıl çalışıyor? Değişken adı küçük harfse, bunu bir etiket olarak ekler (örneğin, customtag olsaydı, <customtag> Merhaba </customtag> alırdım). Bu herhangi bir yerde belgelenmiş mi?
İbrahim

5
Bileşen bir nesnenin özelliğinde depolanırsa, ilk büyük harf gerekmez. var foo = { bar: CustomTag }; return <foo.bar />iyi çalışıyor.
21'de jdunning

29

React.createElementTamlık sağlamak için dinamik bir ad kullanmak istiyorsanız, JSX kullanmak yerine doğrudan da arayabilirsiniz :

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

Bu, yeni bir değişken veya bileşen oluşturmak zorunda kalmaz.

Sahne ile:

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

Gönderen docs :

Belirtilen türde yeni bir React öğesi oluşturun ve döndürün. Type argümanı bir etiket adı dizesi ( 'div'veya gibi 'span') veya bir React bileşen türü (bir sınıf veya bir işlev) olabilir.

JSX ile yazılan kod kullanıma dönüştürülecektir React.createElement(). React.createElement()JSX kullanıyorsanız genellikle doğrudan çağırmazsınız. Daha fazla bilgi için JSX Olmadan Tepki bölümüne bakın .


11

TypeScript kullanıyorsanız, bunun gibi bir hata gördünüz:

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

TypeScript CustomTagbunun geçerli bir HTML etiketi adı olduğunu bilmiyor ve yararsız bir hata veriyor .

Düzeltme için dökme CustomTagolarak keyof JSX.IntrinsicElements!

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

<CustomTag>Hello</CustomTag>

TypeScript kullanıyorum ama döküm bu hatayı veriyor: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

Diğer tüm cevaplar iyi çalışıyor, ancak bunu yaparak bazı ekstra eklemek istiyorum:

  1. Biraz daha güvenlidir. Tür denetiminiz başarısız olsa bile, yine de uygun bir bileşen döndürürsünüz.
  2. Daha beyan edicidir. Bu bileşene bakarak herkes neyin geri dönebileceğini görebilir.
  3. Örneğin 'h1', 'h2' yerine daha esnektir ... Başlığınızın türü için 'sm', 'lg' veya 'birincil', 'ikincil' gibi başka soyut kavramlara da sahip olabilirsiniz.

Başlık bileşeni:

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;

Hangi gibi kullanabilirsiniz

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

veya farklı bir soyut kavramınız olabilir, örneğin aşağıdaki gibi bir boyut sahne tanımlayabilirsiniz:

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;

Hangi gibi kullanabilirsiniz

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

2

Dinamik başlıklar (h1, h2 ...)React.createElement söz konusu olduğunda , bir bileşen bu şekilde geri dönebilir (yukarıda Felix tarafından bahsedilmiştir ).

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

Kompostlanabilirlik için hem aksesuarlar hem de çocuklar geçer.

Örneğe bakın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.