dropWizard
dropWizard

Reputation: 3538

Building a table in react

I'm trying to build a simple table using React and running into a small issue.

Here is the HTML:

<div>  
  <table>
    <tbody id="content">
      <tr>
        <th>Name</th>
        <th>Email</th> 
      </tr>
    </tbody>
  </table>
</div>

And then my React module:

var FriendsContainer = React.createClass({
    getInitialState: function(){
        return {
            data: [
                {'name':'Lorem Ipsum', 'email':'[email protected]'}, 
                {'name':'Caveat Broader', 'email':'[email protected]'},
                {'name':'Runther Brigsby', 'email':'[email protected]'}
            ]
        }
    },

    render: function(){
        var listItems = this.state.data.map(function(person) {
            return(
                <tr>
                    <td>{person['name']}</td>
                    <td>{person['email']}</td>
                </tr>
            )
        });
        return (
            {listItems}
        )
    }
});

I keep getting the error Error: FriendsContainer.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

What am I doing wrong?

Upvotes: 0

Views: 2850

Answers (4)

dropWizard
dropWizard

Reputation: 3538

Finally figured it out:

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>React Tutorial</title>
        <script src="https://npmcdn.com/[email protected]/dist/react.js"></script>
        <script src="https://npmcdn.com/[email protected]/dist/react-dom.js"></script>
        <script src="https://npmcdn.com/[email protected]/browser.min.js"></script>
    </head>
    <body>
        <div id="content">
        </div>
    <script type="text/babel" src="script.js"></script>
    </body>
</html>

React components:

var BuildTable = React.createClass({
    getInitialState: function(){
        return {
            columns: ['name', 'email', 'test'],
            rows: [
                {'name':'brandev balbusor', 'email':'[email protected]'},
                {'name': 'lorem ipsum', 'email':'[email protected]'},
                {'name':'titus maldav', 'email':'email3#gmail.com'}
            ]
        }
    },

    render: function(){
        return (
            <table>
                <CreateColumns col={this.state.columns} />
                <CreateRows people={this.state.rows} />
            </table>
        )   
    }
});

var CreateColumns = React.createClass({
    render: function(){
        var columns = this.props.col.map(function(column){
            return <th> {column} </th>
        });

        return (
            <thead>
                <tr>
                    {columns}
                </tr>
            </thead>
        )
    }
});

var CreateRows = React.createClass({
    render: function(){
        var data = this.props.people.map(function(person){
            return (
                <tr>
                    <td>{person['name']}</td>
                    <td>{person['email']}</td>
                </tr>
            )
        });
        return (
            <tbody>
                {data}
            </tbody>
        )
    }
});

Upvotes: 0

Ravi Ojha
Ravi Ojha

Reputation: 168

If you look at the error message it says, ...You may have returned undefined, an array or some other invalid object...., that's right, the return type of render is JSX.Element as,

---
render(): JSX.Element {
retrun <JSX.Element>{Something}
}

Something: for you question it should be table.

Upvotes: 0

m1kael
m1kael

Reputation: 2851

Your map call generates an array which you must wrap in a parent element (tbody in this case) as a React component has to have a single root element. You'll have to include your table header there too, and optionally the table tag:

    return (
        <table>
            <tbody id="content">
                <tr>
                    <th>Name</th>
                    <th>Email</th> 
                </tr>
                {listItems}
            </tbody>
        </table>
    );

Next, alter your map callback so that it also accepts 'i' (index) so you can assign unique keys to your tr's:

var listItems = this.state.data.map(function(person, i) {
        return(
            <tr key={i}>
                <td>{person['name']}</td>
                <td>{person['email']}</td>
            </tr>
        )
    });

This should do it.

Upvotes: 2

saiyan
saiyan

Reputation: 572

you should be atleast wrap in a div like

return (
            <div>{listItems}</div>
        )

and as @Dave Newton said there should be a higher level tag like table instead of div.As per error the render method should return null or empty <div> not anything else.

Upvotes: 0

Related Questions