简体   繁体   中英

Fetch and array of objects from a database and displaying it with react

I was trying to fetch an array of objects when I encounter this problem. Sorry for my messy code, I'm a beginner.

export class App extends Component {
  state ={
    character:[]
  }
  componentDidMount(){

     fetch('https://swapi.dev/api/people/').then(data => data.json()).then(res =>{
     this.setState(() =>{
       const ar = res.results

       return {
         character: ar
       }
     })
    })


  }
  render() {
    return (
      <div>
         test

          {console.log(this.state.character[0])}
      </div>
    )
  }
}

That code works fine for me at first until I changed the console log to {console.log(this.state.character[0].name)} it says "cannot read property of an undefined" even though the first line displays the object perfectly

Your App component fetches the data in componentDidMount life cycle method which will execute after the first mount. {console.log(this.state.character[0].name)} shows error "cannot read property of undefined because when the component mounts for first time, the data is not available yet, which means this.state.character is still an empty array. So when try to access this.state.character[0].name , its like saying give me the value of undefined.name which will give you an error because name property does not exist on undefined . To fix this issue you can check if character.length in a conditional and then try to access .name .

Example

render() {
    return (
      <div>
         test

          {this.state.character.length && <p>{this.state.character[0].name}</p>}
      </div>
    )
  }

Fetch is asynchronous so you will take some time to get the result but before that your jsx is called already. So it is good to use conditional jsx. Please check the complete example as below where I shown all the name of character array under li element.

export class App extends React.Component {
    state = {
        character: []
    };

    componentDidMount() {

        fetch('https://swapi.dev/api/people/').then(data => data.json()).then(res => {
            this.setState(() => {
                const ar = res.results;

                return {
                    character: ar
                }
            })
        })
    }

    render() {
        return (
            <div>
                test
                {
                    this.state.character && this.state.character.length && this.state.character.map((item, index) => {
                       return <li key={index}>{item.name}</li>
                    })
                }
            </div>
        )
    }
}

export default App;

So that will not work. Data is not there yet. There are bunch of ways to workaround it. Most simple one is to have object structure predefined in the state object, which is not very dynamic. Otherwise simple .length + if + else will do the job.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM