There is a table, in which the product groups are rendered:

Product groups

When clicking on a line, several more lines should be added to it (the group is expanded), like this:

enter image description here

(when clicking on the blue line, 2 more red lines were rendered)

I try to do it like this:

import React from "react"; class App extends React.Component { renderGroups(groups) { return groups.map(({ group: { name } }, index) => ( <tr key={index} className="group" onClick={this.onGroupToggle}> <td>{name}</td> <td>g-1.1</td> <td>g-1.2</td> <td>g-1.3</td> <td>g-1.4</td> <td>g-1.5</td> </tr> )); } renderProducts(products) { return products.map(({ name }) => ( <tr key={index} className="product"> <td>{name}</td> <td>g-1.1</td> <td>g-1.2</td> <td>g-1.3</td> <td>g-1.4</td> <td>g-1.5</td> </tr> )); } onGroupToggle() { console.log("onGroupToggle"); // какие то непонятные действия // которые должны привести к инжекту tr.product после tr.group } render() { const groups = [ { group: { group_id: 1, name: 'Телефоны' }, products: [ { product_id: 1, name: 'iPhone 7' }, { product_id: 1, name: 'iPhone 7 Plus' } ] } ]; return ( <table border="1"> <thead> <tr> <th>name</th> <th>1</th> <th>2</th> <th>3</th> <th>4</th> <th>5</th> </tr> </thead> <tbody> {this.renderGroups(groups)} </tbody> </table> ); } } App.propTypes = { example: React.PropTypes.object }; export default App; 

How to implement it correctly on React, because I can’t return 2 tr inside renderGroups.

 renderProducts(products) { return products.map(({ name }) => ( <tr key={index} className="group"> <td>{name}</td> <td>g-1.1</td> <td>g-1.2</td> <td>g-1.3</td> <td>g-1.4</td> <td>g-1.5</td> </tr> <tr key={index} className="product"> <td>{name}</td> <td>g-1.1</td> <td>g-1.2</td> <td>g-1.3</td> <td>g-1.4</td> <td>g-1.5</td> </tr> <tr key={index} className="product"> <td>{name}</td> <td>g-1.1</td> <td>g-1.2</td> <td>g-1.3</td> <td>g-1.4</td> <td>g-1.5</td> </tr> )); } 

How to do it right?

UPDATE

Example: there is a Tables component which accepts TableRows components as props which renders all rows in the table (inside this component I wrap a string with the name of the group and product lines in tbody) but if this component returns several "tbody" feedl returns an error

TableRows.render (): A valid ReactComponent must be returned. You may have returned an undefined object.

    1 answer 1

    The standard hack of this restriction for the case when you need to return several rows of a table is to wrap these rows in tbody and return this wrapper from render. tbody in the table can be several and the structure will not be greatly changed.

    Something like that:

     renderMultipleRows(){ return <tbody> <tr></tr> <tr></tr> </tbody> } 

    You can also return from the function (but not the render method the reactance of the component!) Array of jsx nodes. In this case, it is necessary to assign each node to the key based on the semantics of the nodes, otherwise the reaction will spit vornings.

     const AwesomeComponent = React.createClass({ renderRows: function(){ return [ <tr key="smth"></tr>, <tr key="smthelse"></tr> ] }, render: function(){ return <tbody>{this.renderRows()}</tbody> } }); 
    • And if all the rows are moved to a separate component, for example TableRows, again, it turns out that the component must return an array of elements, how to avoid this? - Pavel
    • @Pavel, I did not understand how your situation is different from what I described. Give an example. In general, in general, you need to remember that jsx in javascript compiles according to transparent rules. And this very restriction of returning one node from the render - it happens from js, while it is impossible to bypass it in a blank way. Think of the jsx component as a function call and everything will become clearer. - Duck Learns to Take Cover
    • The good news is that this restriction is not very restrictive. It occurs to me two cases where it is really useful: 1. the rows of the table calmly turn around here in tbody, 2. tricky permutations of the child elements of the container, solved by the keyed fragment: facebook.imtqy.com/react/docs/create-fragment.html - Duck Learns to Take Cover
    • Added an example to a comment - Pavel
    • @Pavel if the problem is to return several elements not from the render method of the component's reactance, but simply from some function inside the component, then there is actually no problem. Return an array of elements, jsx will understand. Completed. - Duck Learns to Take Cover