简体   繁体   中英

React js fetch API with componentDidMount()

I am learning React.js and trying to fetch API with fetch() and I tried to use componentDidMount() but I have a problem, you can see the pic at the end of the post.

import React, { Component } from 'react'


export default class App extends Component {
    
    state = {
      weather: []
    };
    
    
    fetchData() {
        fetch('prevision-meteo.ch/services/json/rochelle-17')
        .then((response) => response.json())
        .then((obj) => {
            console.log('javascript object: ', obj)
            this.setState({ weather: obj.results});
        })
        .catch((error) => {
            console.error(error)
          })
    }
    componentDidMount() {
        console.log('Le composant App est monté sur le DOM !')
        this.fetchData();
    }
    render() {
        return (
            <div>
                {this.state.weather&& this.state.weather.map((weatherRecord) => ( 
                  <div key={weatherRecord.city_info.name}>{weatherRecord.city_info.name}</div>
                 ))}
                Hello World !
                <button /*onClick={() => this.fetchData()}*/> Click me</button>
            </div>
        )
    }
}

I want to get the name of city_info in my page but didn't work!

This is the results in the console, can anyone help me? 在此处输入图片说明

Setting state is asynchronous so React is rendering before the state has been set. What you can do is put in a short circuit condition this.state.weather && to check if the weather array exists and only when it is available will the map operation be performed and you shouldn't get any errors.

import React, { Component } from 'react'


export default class App extends Component {
    
    state = {
      weather: []
    };
    
    
    fetchData() {
        fetch('http://localhost:3000/rochelle-17.json')
        .then((response) => response.json())
        .then((obj) => {
            //console.log('javascript object: ', obj)
            this.setState({ weather: obj.results});
        })
    }
    componentDidMount() {
        console.log('Le composant App est monté sur le DOM !')
        this.fetchData();
    }
    render() {
        return (
            <div>
                {this.state.weather&& this.state.weather.map((weatherRecord) => (
                    <div key={weatherRecord.city_info.name}></div>
                ))}
                Hello World !
                <button /*onClick={() => this.fetchData()}*/> Click me</button>
            </div>
        )
    }
}

Some Notes:

  • The newer versions of React support setting initial state like this, which is a bit cleaner:

     state = { weather: [] }
  • It's also good practice to catch errors in case the API call fails. You can simply use .catch like this after the last .then() :

     .catch((error) => { console.error(error) })
  • Since ES6 you don't need to use return for the <div> you are rendering. You can simply use map with curved brackets () instead of curly brackets {} to implicitly return

     {this.state.weather&& this.state.weather.map((weatherRecord) => ( <div key={weatherRecord.city_info.name}></div> ))}

Try this

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      wheather: null
    };
  }

  fetchData() {
    fetch("http://localhost:3000/rochelle-17.json")
      .then((response) => {
        return response.json();
      })
      .then((obj) => {
        //console.log('javascript object: ', obj)
        this.setState({ wheather: obj });
      });
  }
  componentDidMount() {
    console.log("Le composant App est monté sur le DOM !");
    this.fetchData();
  }
 render() {
    return (
      <div>
        {this.state.wheather
          && <div key={this.state.wheather.city_info.name}>{this.state.wheather.city_info.name}</div>
        }
        Hello World !
        <button /*onClick={() => this.fetchData()}*/> Click me !</button>
      </div>
    )
  }
}

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