Search code examples
reactjsjavascript-objectstypeerrorarray.prototype.mapreact-lifecycle

Displaying fetched data issue : objects not valid as React child / TypeError : undefined


I would like to display data fetched from an api, by using lifecycle methods. I manage to fetch the data (object) and to populate my data in the state (array). But I can't display the values in the return part.

The first part of the code that seems to work, for readability I removed the error/loading part :

class App extends Component {
    constructor(props) {
        super(props);
    
        this.state = {
          data: [], //putting data in the state
        };
      }
    
    async componentDidMount() {
        fetch("https://covid19.mathdro.id/api")
        .then((response) => response.json())
        .then(
            (data) => {
                this.setState({
                confirmed: data.confirmed, //populate data in this.state
                recovered: data.recovered,
                deaths: data.deaths,
            });
            }
          );
      }
    
    render() {
        const { confirmed, recovered, deaths } = this.state;
        console.log(confirmed, recovered, deaths);
        ...
    }
    
    export default App;

Here is the first return I tried :

return ( <div> {(confirmed, recovered, deaths)} </div>);

I got the

Error: Objects are not valid as a React child (found: object with keys {value, detail}). If you meant to render a collection of children, use an array instead.

Console.log does indeed return objects :

Object { value: 42280709, detail: "https://covid19.mathdro.id/api/confirmed" } Object { value: 28591681, detail: "https://covid19.mathdro.id/api/recovered" } Object { value: 1145557, detail: "https://covid19.mathdro.id/api/deaths" }

By the way, console.log(confirmed.value) doesn't return anything, why?

So I decided to use the Array.prototype.map() :

return (
    <div> 
        {this.state.confirmed.map(i => (<div>{i.value}</div>))} 
    </div>);

And now I got the

TypeError: confirmed is undefined

I don't understand this error, how can console.log(confirmed) return something if it is undefined?

Other paths I explored : using JSON.parse, putting key in the map, removing the {}, ..

I went through several stackoverflow questions, but still don't understand what to change : React render: Objects are not valid as a React child Objects are not valid as a React child. If you meant to render a collection of children, use an array instead

Any clues? Thanks !


Solution

  • I have checked the API that you've been using, I see confirmed, recovered, deaths are objects not arrays(That's why you're getting those error). you should do the following code.

    class App extends Component {
        constructor(props) {
            super(props);
            this.state = { confirmed: {}, recovered: {}, deaths: {} };
          }
        
        async componentDidMount() {
          fetch("https://covid19.mathdro.id/api")
          .then((response) => response.json())
          .then(
              (data) => {
                const { confirmed, recovered, deaths } = data
                this.setState({ confirmed, recovered, deaths });
              }
            );
          }
        
        render() {
            const { confirmed, recovered, deaths } = this.state;
            return (
              <div>
                <div>Confirmed: { confirmed.value || 0}</div>
                <div>Recovered: { recovered.value || 0}</div>
                <div>Deaths: { deaths.value || 0 }</div>
              </div>
            )
        }
    }
        
    export default App;