Search code examples
javascriptreactjskeyfetch-api

I listed my key prop, but still getting the following error: Each child in a list should have a unique "key" prop


I am trying to fetch data from a rest API and then render it as text on my browser. However, I keep getting the following error:

index.js:1 Warning: Each child in a list should have a unique "key" prop.

I have my key prop listed below. Can someone tell what I am doing wrong? I listed my key prop below thinking it would work this way in the render (I used this for another API call in a different project and it worked).

This is how the joke is set up in the API:

{
  "id": "R7UfaahVfFd",
  "joke": "My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.",
  "status": 200
}

Here is my code for fetching it:

import React, { Component } from 'react';


class JokesApi extends Component {
    constructor(props){
        super(props);

        this.state = {
            jokes: [],
        };
    }

    componentDidMount(){
        fetch('https://cors-anywhere.herokuapp.com/https://icanhazdadjoke.com/', {
            headers: {
                'Content-Type': 'appliction/json',
                'Accept': 'application/json'
            }
        })
            .then(response => response.json())
            .then(data => this.setState(prev => ({jokes: prev.jokes.concat(data.joke)})))
    }

    render () {
      var jokes;
        return (
            <ul>
                {this.state.jokes.map(joke => 
                  <div key={joke.id}>
                     <p>{jokes}</p>
                  </div>    
                )}
            </ul>
        )
    }
}


export default JokesApi;

Solution

  • You set the array to the string representing the joke itself on fetch (data.joke) rather than the object itself (data), so joke.id ends up being undefined.

    rather than getting this.state.jokes that looks like this:

    [{
      "id": "R7UfaahVfFd",
      "joke": "My dog used to chase people on a bike a lot. It got so bad I had to take his bike away.",
      "status": 200
    }]
    

    you are getting data that looks like this:

    ["My dog used to chase people on a bike a lot. It got so bad I had to take his bike away."]
    

    Here is the working code:

    import React, { Component } from 'react';
    
    class JokesApi extends Component {
        constructor(props){
            super(props);
    
            this.state = {
                jokes: [],
            };
        }
    
        componentDidMount(){
            fetch('https://cors-anywhere.herokuapp.com/https://icanhazdadjoke.com/', {
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                }
            })
                .then(response => response.json())
                .then(data => this.setState(prev => ({jokes: prev.jokes.concat(data)})))
        }
    
        render () {
          console.log(this.state.jokes);
            return (
                <ul>
                    {this.state.jokes.map(joke => 
                      <div key={joke.id}>
                         <p>{joke.joke}</p>
                      </div>    
                    )}
                </ul>
            )
        }
    }
    
    export default JokesApi;