Как я могу отображать элементы sibling без их переноса в родительский тег?

В большинстве случаев наличие родительского тега не является проблемой.

React.createClass({
    render: function() {
        return (
            <tbody>
                <tr><td>Item 1</td></tr>
                <tr><td>Item 2</td></tr>
            </tbody>
        );
    }
});

Но есть случаи, когда имеет смысл иметь элементы-братья в одной функции рендеринга без родителя, и особенно в случае таблицы, вы не хотите обертывать строку таблицы в div.

React.createClass({
    render: function() {
        return (
            <tr><td>Item 1</td></tr>
            <tr><td>Item 2</td></tr>
        );
    }
});

Второй пример дает следующую ошибку: Adjacent XJS elements must be wrapped in an enclosing tag while parsing file.

Как я могу отобразить два элемента sibling без их обертки в <div> или что-то подобное?

Ответ 1

Woohoo! Команда Реагента, наконец, обратилась к этой функции. Начиная с версии React v16.0, вы можете:

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
      <tr key="a"><td>Item 1</td></tr>,
      <tr key="b"><td>Item 2</td></tr>
  ];
}

Смотрите полное сообщение в блоге, объясняющее "Новые типы возвращаемых рендерингов: фрагменты и строки" здесь.

Ответ 2

Это ограничение в настоящее время, но, скорее всего, будет исправлено в какой-то момент в будущем (есть некоторые открытые проблемы в репозитории github).

Теперь вы можете использовать функцию, которая возвращает массив (это в основном компонент без состояния):

function things(arg, onWhatever){
    return [
        <tr><td>Item 1</td></tr>,
        <tr><td>Item 2</td></tr>
    ];
}

И используйте это в своем компоненте.

return (
    <table><tbody>
      {things(arg1, this.handleWhatever)}
      {things(arg2, this.handleWhatever)}
    </tbody></table>
);

Update

В React 16 вы сможете вернуть массив из рендера.

Ответ 3

Вы можете заключить его в скобки следующим образом:

React.createClass({
    render: function() {
        return (
          [
            <tr><td>Item 1</td></tr>
            <tr><td>Item 2</td></tr>
          ]
        );
    }
});

Ответ 4

Этот пример хорошо работает для меня:

let values = [];

if (props.Values){
  values = [
    <tr key={1}>
      <td>props.Values[0].SomeValue</td>
    </tr>
  ,
    <tr key={2}>
        <td>props.Values[1].SomeValue</td>
        </tr>
    ];
}

return (
    <table className="no-border-table table">
      <tbody>
        <tr>
            <th>Some text</th>
        </tr>
        {values}
      </tbody>
    </table>
)

Ответ 5

Что-то вроде этого синтаксиса работало для меня

this.props.map((data,index)=>{return( [ <tr>....</tr>,<tr>....</tr>];)});