Как вернуть несколько строк JSX в другой оператор return в React?
Одиночная линия работает нормально
render: function () {
return (
{[1,2,3].map(function (n) {
return <p>{n}</p>
}}
);
}
не для нескольких строк
render: function () {
return (
{[1,2,3].map(function (n) {
return (
<h3>Item {n}</h3>
<p>Description {n}</p>
)
}}
);
}
Спасибо.
Ответы
Ответ 1
Попробуйте вспомнить теги как вызовы функций (см. docs). Тогда первый становится:
{[1,2,3].map(function (n) {
return React.DOM.p(...);
})}
И второй:
{[1,2,3].map(function (n) {
return (
React.DOM.h3(...)
React.DOM.p(...)
)
})}
Теперь должно быть ясно, что второй фрагмент действительно не имеет смысла (вы не можете вернуть больше одного значения в JS). Вы должны либо обернуть его в другой элемент (скорее всего, то, что вы хотите, таким образом вы также можете предоставить действительное свойство key
), или вы можете использовать что-то вроде этого:
{[1,2,3].map(function (n) {
return ([
React.DOM.h3(...),
React.DOM.p(...)
]);
})}
С сахаром JSX:
{[1,2,3].map(function (n) {
return ([
<h3></h3>, // note the comma
<p></p>
]);
})}
Вам не нужно сгладить результирующий массив, React сделает это за вас. См. Следующий скрипт http://jsfiddle.net/mEB2V/1/. Опять же: объединение двух элементов в div/раздел, скорее всего, будет более долгосрочным.
Ответ 2
Кажется, старый ответ о возврате массива больше не применяется (возможно, с React ~ 0.9, как @dogmatic69 написал в комментарии).
Документы говорят, что вам нужно вернуть один узел:
Максимальное количество корневых узлов JSX
В настоящее время в компоненте render вы можете только вернуть один узел; если у вас есть, скажем, список divs для возврата, вы должны обернуть ваши компоненты в div, span или любой другой компонент.
Не забывайте, что JSX компилируется в обычный JS; возвращение двух функций не делает синтаксического смысла. Точно так же не ставьте более одного ребенка в тройной.
Во многих случаях вы можете просто обернуть вещи в <div>
или <span>
.
В моем случае я хотел вернуть несколько <tr>
s. Я завернул их в <tbody>
- таблице разрешено иметь несколько тел.
EDIT: с React 16.0 возвращение массива, по-видимому, разрешено снова, если каждый элемент имеет key
: https://facebook.github.io/react/blog/2017/09/26/react-v16.0. HTML # новых рендеринг-возвратные типы-фрагменты и-строка
EDIT: React 16.2 позволяет вам окружать список элементов с помощью <Fragment>…</Fragment>
или даже <>…</>
, если вы предпочитаете это в массиве: https://blog.jmes.tech/react-fragment и-семантическое HTML/
Ответ 3
Начиная с React v16.0.0, можно возвращать несколько элементов, помещая их в Array
render() {
return (
{[1,2,3].map(function (n) {
return [
<h3>Item {n}</h3>.
<p>Description {n}</p>
]
}}
);
}
Также из React v16.2.0 представлена новая функция под названием React Fragments
которую можно использовать для обертывания нескольких элементов.
render() {
return (
{[1,2,3].map(function (n, index) {
return (
<React.Fragment key={index}>
<h3>Item {n}</h3>
<p>Description {n}</p>
</React.Fragment>
)
}}
);
}
Согласно документации:
Обычный шаблон в React - компонент возвращает несколько элементов. Фрагменты позволяют группировать список детей без добавления дополнительных узлов в DOM.
Фрагменты, объявленные с явным синтаксисом, могут иметь ключи. Вариант использования для этого - сопоставление коллекции с массивом фрагментов - например, для создания списка описания:
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>
);
}
ключ является единственным атрибутом, который может быть передан фрагменту. В будущем мы можем добавить поддержку дополнительных атрибутов, таких как обработчики событий.
Ответ 4
Кроме того, вы можете захотеть вернуть несколько элементов списка в некоторой вспомогательной функции внутри компонента React. Просто верните массив узлов html с атрибутом key
:
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>,
]
}
}
Ответ 5
Здесь вы можете использовать createFragment
.
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>
})
)}
(используя здесь синтаксис ES6 и JSX)
сначала нужно добавить пакет react-addons-create-fragment
:
npm install --save react-addons-create-fragment
Преимущество решения Jan Olaf Krems: реакция не жалуется на недостающие key
Ответ 6
обновленный
Используйте React Fragment. Это просто. Ссылка на фрагмент документации.
render() {
return (
<>
{[1,2,3].map((value) => <div>{value}</div>)}
</>
);
}
Старый ответ - устарел
С React> 16 вы можете использовать ответную смесь.
import { Composite } from 'react-composite';
// ...
{[1,2,3].map((n) => (
<Composite>
<h2>Title {n}</h2>
<p>Description {n}</p>
</Composite>
))};
Конечно, должен быть установлен реагирующий композит.
npm install react-composite --save