Umair
Umair

Reputation: 89

Getting this warning "Functions are not valid as a React child"

I am trying to render a list of movies from an array object in an html table format. I am getting this warning:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.

import React from 'react';
import {movies} from '../services/fakeMovieService';

class Movies extends React.Component {
constructor(props) {
    super(props);

    this.tableFormat = this.tableFormat.bind(this);
}

    tableFormat() {
        movies.map((movie) => {
            return (
                <tr>
                    <td key={movie._id}>{movie.title}</td>
                </tr>
            );
        });
    }


    render() {

        return (
            <table className="table">
                <thead>
                    <tr>
                        <th>Title</th>
                        <th>Genre</th>
                        <th>Stock</th>
                        <th>Rate</th>
                    </tr>
                </thead>
                <tbody>
                    {this.tableFormat()}
                </tbody>
            </table>

        );
    }
}

export default Movies;

Upvotes: 1

Views: 738

Answers (3)

Treycos
Treycos

Reputation: 7492

You forgot to call your function.

<tbody>
   {this.tableformatter()}
</tbody>

But even by doing, I don't think the result is going to be what you expect.

To render an array of elements in React you should use the map function as said in the docs.

The following result would be :

<tbody>
    {movies.map(movie => 
        <tr key={movie.title}>
            <td>{movie.title}</td>
        </tr>
    )}
</tbody>

EDIT:

I made a typo and put movies instead of movie.

The following code should do everything you are looking for using map and inline conditions:

const movies = [
    {
        title: "Spooky",
        genre: 'eziojgf',
        stock: 'nope',
        rate: 87
    },
    {
        title: "Sharknado",
        genre: 'shitty',
        stock: 'yes',
    },
    {
        title: "haha yes"
    },
    {
        title: "uhmmmm",
        rate: -5
    }
]

class Movies extends React.Component {
    constructor(props) {
        super(props);

    }

    render() {
        return (
            <table className="table">
                <thead>
                    <tr>
                        <th>Title</th>
                        <th>Genre</th>
                        <th>Stock</th>
                        <th>Rate</th>
                    </tr>
                </thead>
                <tbody>
                    {movies.map(movie =>
                        <tr key={movie.title}>
                            {['title', 'genre', 'stock', 'rate'].map(category => <td key={category}>{movie[category]}</td>)}
                        </tr>
                    )}
                </tbody>
            </table>
        );
    }
}

ReactDOM.render(<Movies />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.1/umd/react-dom.production.min.js"></script>
<div id='root'>

Upvotes: 1

Shevchenko Viktor
Shevchenko Viktor

Reputation: 5396

here is the right way how to resolve this with React

function TableFormatter ({title /* , and other props genre, rate etc. *//}) {
  return (
    <tr>
      <td>{title}</td>
      {/* you may want to add other td here *//}
    </tr>
  )
}

function Table({movies}) {
  render() {
    return (
      <table className="table">
        <thead>
          <tr>
            <th>Title</th>
            <th>Genre</th>
            <th>Stock</th>
            <th>Rate</th>
          </tr>
        </thead>
        <tbody>
          {movies.map(movie => <TableFormatter key={movie.id} {...movie} />)}
        </tbody>
      </table>
    );
  }
}

Upvotes: 0

Umair Farooq
Umair Farooq

Reputation: 1823

Please execute function as following:

<tbody>
   {this.tableformatter()}
</tbody>

Upvotes: 0

Related Questions