React'te başka bir dönüş ifadesinde birden çok satır JSX nasıl döndürülür?


101

Tek satır iyi çalışıyor

render: function () {
  return (
    {[1,2,3].map(function (n) {
      return <p>{n}</p>
    }}
  );
}

birden çok hat için değil

render: function () {
  return (
    {[1,2,3].map(function (n) {
      return (
        <h3>Item {n}</h3>
        <p>Description {n}</p>
      )
    }}
  );
}

Teşekkürler.


1
Bu özel konu hakkında daha fazla bilgi için: github.com/facebook/react/issues/2127
artı

istemiyor return ("asdf" "asdf");musunreturn ["asdf", "asdf"];
neaumusic

Yanıtlar:


150

Etiketleri işlev çağrıları olarak düşünmeye çalışın ( dokümanlara bakın ). Sonra ilki şu olur:

{[1,2,3].map(function (n) {
  return React.DOM.p(...);
})}

Ve ikincisi:

{[1,2,3].map(function (n) {
  return (
    React.DOM.h3(...)
    React.DOM.p(...)
  )
})}

Şimdi, ikinci kod parçacığının gerçekten anlamlı olmadığı anlaşılmalıdır (JS'de birden fazla değer döndüremezsiniz). Ya başka bir öğeye sarmalısınız (büyük olasılıkla ne isterseniz, bu şekilde geçerli bir keymülk de sağlayabilirsiniz ) ya da şöyle bir şey kullanabilirsiniz:

{[1,2,3].map(function (n) {
  return ([
    React.DOM.h3(...),
    React.DOM.p(...)
  ]);
})}

JSX şekeri ile:

{[1,2,3].map(function (n) {
  return ([
    <h3></h3>, // note the comma
    <p></p>
  ]);
})}

Ortaya çıkan diziyi düzleştirmenize gerek yok, React bunu sizin için yapacak. Aşağıdaki keman bölümüne bakın http://jsfiddle.net/mEB2V/1/ . Tekrar: İki öğeyi bir div / bölüme sarmak büyük olasılıkla uzun vadede daha iyi olacaktır.


4
Evet, aslında açıkça belgelendi facebook.github.io/react/tips/…
Shawn

1
Düzleştirme biti olmadan return ([...]) kullanmak bana tam olarak istediğim gibi işaretlemeyi verir, ancak döndürülen dizi düz eğimli olmamalıdır, ancak benim özel durumumda son çıktıyı etkilemez. Yoksa öyle mi?
Shawn

Teşekkürler! TIL! Cevabımı, düzleştirmenin isteğe bağlı olduğunu gösteren bir JSFiddle bağlantısını içerecek şekilde güncelleme. React belgelerine bağlantı da içerecektir.
Jan Olaf Krems

13
Bu artık çalışmıyor (0.9ish itibariyle)Uncaught Error: Invariant Violation: Product.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
dogmatic69

2
@TimFletcher Bir bileşeni oluşturmanın parçası olarak bir dizi döndürmenin bir sakıncası yoktur , örn <div>{ this.props.foos.map(function() { return <Foo /> }) }</div>. Ancak renderbileşenin işlevi, diziyi sarmadan, örneğin bir div olarak döndüremez.
Henrik N

35

Görünüşe göre bir diziyi döndürmekle ilgili eski cevap artık geçerli değil (belki React ~ 0.9'dan beri, @ dogmatic69'un bir yorumda yazdığı gibi ).

Dokümanlar , tek bir düğüm döndürmeniz gerektiğini söylüyor:

Maksimum JSX Kök Düğümü Sayısı

Şu anda, bir bileşenin işlemesinde yalnızca bir düğüm döndürebilirsiniz; Örneğin, döndürülecek bir div listeniz varsa, bileşenlerinizi bir div, span veya başka bir bileşenin içine sarmalısınız.

JSX'in normal JS'de derlendiğini unutmayın; iki işlevi döndürmek gerçekten sözdizimsel bir anlam ifade etmez. Aynı şekilde, üç çocuğa birden fazla çocuk koymayın.

Çoğu durumda, her şeyi a <div>veya a'ya sarabilirsiniz <span>.

Benim durumumda, birden çok <tr>e- postayı döndürmek istedim . Onları bir <tbody>- bir masanın birden fazla gövdeye sahip olmasına izin veriliyor.

DÜZENLEME: React 16.0'dan itibaren, her öğenin bir key: https://facebook.github.io/react/blog/2017/09/26/react-v16.0.html olması koşuluyla, bir dizi döndürmeye görünürde tekrar izin verilir # new-render-return-types-fragments-and-strings

DÜZENLEME: 16.2 Birlikte öğelerin listesini çevreleyen sağlar Tepki <Fragment>…</Fragment>hatta <>…</>, bir diziye tercih edin: https://blog.jmes.tech/react-fragment-and-semantic-html/


3
Birden fazla iade etmek isterseniz ne yapabilirsiniz <li>? Her <ul>
şeyi paketleyemeyeceğimi

@Banjocat Korkarım bilmiyorum: / Listeleri iç içe geçirme izniniz var , böylece <li><ul><li>one</li><li>two</li></ul></li>sizin durumunuzda işe yarıyorsa gibi bir şey geri verebilirsiniz . Veya: Bir sarmalama div'i kesinlikle geçerli olmaz, ancak ilgili tüm tarayıcılarda iyi sonuç verebilir mi? Eğer denerseniz, bize bildirin.
Henrik N

1
@Banjocat ... Sorunuza daha iyi bir cevap vermeyi çok isterim. Belki de bunu sıradan bir yığın aşımı sorusu olarak düşünmeli ve farklı bir yanıt alıp almadığınızı görmelisiniz.
user1175849

@ user1175849 Belki sen :) sonra bu soruyu sonrası olabilir
Henrik N

1
@HenrikN FWIW, bir "alt kümesini" örten libir bölgesi spanya da divbenim için de işe yaramadı. Div, oluşturmayı ciddi şekilde bozdu ve en azından benim kullanım durumumda, açıklık CSS'yi karıştırdı. 2 ¢: Birkaç alt kümeyi döndürmeye çalışmak libir kod kokusudur. Biz kullanıyorlardı ulaçılan menüden bir tür, ve ben başlangıçta bir "bölümlerini" dönmek birçok bileşeni istedik lis. Sonunda, tüm menü kodunu tek bir bileşene "sabitlenmiş" bir şekilde yerleştirmek , birden çok kaynaktan gelen ulURL'lere takılmaktan daha iyidir li. Bence kullanıcı arayüzü için zihinsel modeli de biraz daha temiz hale getirdi.
ruffin

13

Gönderen v16.0.0 Tepki itibaren, bir dahilinde sarılarak Dönüş birden elemanları mümkündürArray

render() {
  return (
    {[1,2,3].map(function (n) {
      return [
        <h3>Item {n}</h3>.
        <p>Description {n}</p>
      ]
    }}
  );
}

Ayrıca React v16.2.0'dan , React Fragmentsbirden fazla öğeyi sarmak için kullanabileceğiniz yeni bir özellik tanıtıldı.

render() {
  return (
    {[1,2,3].map(function (n, index) {
      return (
        <React.Fragment key={index}>
            <h3>Item {n}</h3>
            <p>Description {n}</p>
        </React.Fragment>
      )
    }}
  );
}

Belgelere göre:

React'teki yaygın bir model, bir bileşenin birden fazla öğe döndürmesidir. Parçalar, DOM'a fazladan düğüm eklemeden bir alt öğe listesini gruplamanıza olanak tanır.

Açık sözdizimi ile bildirilen parçalar anahtarlara sahip olabilir. Bunun bir kullanım örneği, bir koleksiyonun bir dizi parçayla eşleştirilmesidir - örneğin, bir açıklama listesi oluşturmak için:

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // Without the `key`, React will fire a key warning
        <React.Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}

anahtar, Fragment'a aktarılabilen tek özelliktir. Gelecekte, olay işleyicileri gibi ek özellikler için destek ekleyebiliriz.


7

Ayrıca, bir React bileşeni içindeki bazı yardımcı işlevlerde birkaç liste öğesi döndürmek isteyebilirsiniz. keyÖzniteliğe sahip bir dizi html düğümünü döndürmeniz yeterlidir:

import React, { Component } from 'react'

class YourComponent extends Component {
  // ...

  render() {
    return (
      <ul>
        {this.renderListItems()}
      </ul>
    )
  }      

  renderListItems() {
    return [
      <li key={1}><a href="#">Link1</a></li>,
      <li key={2}><a href="#">Link2</a></li>,
      <li key={3} className="active">Active item</li>,
    ]
  }
}

3

Güncellenmiş

React Fragment kullanın. Basit. Bağlantı parçası belgelerine.

render() {
  return (
    <>
    {[1,2,3].map((value) => <div>{value}</div>)}
    </>
  );
}

Eski cevap - eski

React> 16 ile react-composite kullanabilirsiniz .

import { Composite } from 'react-composite';

// ...

{[1,2,3].map((n) => (
  <Composite>
    <h2>Title {n}</h2>
    <p>Description {n}</p>
  </Composite>
))};

Elbette react-composite'in yüklenmesi gerekiyor.

npm install react-composite --save

2

createFragmentBurada kullanabilirsiniz .

https://facebook.github.io/react/docs/create-fragment.html

import createFragment from 'react-addons-create-fragment';
...
{[1,2,3].map((n) => createFragment({
    h: <h3>...</h3>,
    p: <p>...</p>
  })
)}

(burada ES6 ve JSX sözdizimini kullanarak)

önce react-addons-create-fragmentpaketi eklemelisiniz :

npm install --save react-addons-create-fragment

Jan Olaf Krems'in çözümüne göre avantaj: Eksiklerden şikayetçi değil key


Yanılıyorsam düzelt ama anahtarları elle ekleyebilirsiniz. jan's örneğini kullanarak: ilk dizi öğesi örneğin <h3 key = {i}> </h3> alır ve ikinci dizi öğesi, <p> key = {i + '-foo'}> </p>
nerdess

1

React fragmanı ile basittir <></>ve React.Fragment:

return (
    <>
      {[1, 2, 3].map(
        (n, index): ReactElement => (
          <React.Fragment key={index}>
            <h3>Item {n}</h3>
            <p>Description {n}</p>
          </React.Fragment>
        ),
      )}
    </>
  );
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.