简体   繁体   中英

Multiple Axios Requests Into ReactJS State

So I have been placing the following code within my React JS component and I am basically trying to put both API calls into one state called vehicles however I am getting an error with the following code:

componentWillMount() {

    // Make a request for vehicle data

    axios.all([
      axios.get('/api/seat/models'),
      axios.get('/api/volkswagen/models')
    ])
    .then(axios.spread(function (seat, volkswagen) {
      this.setState({ vehicles: seat.data + volkswagen.data })
    }))
    //.then(response => this.setState({ vehicles: response.data }))
    .catch(error => console.log(error));
  }

Now I am guessing I can't add two sources of data like I have this.setState({ vehicles: seat.data + volkswagen.data }) however how else can this be done? I just want all of the data from that API request to be put into the one state.

This is the current error I am receiving:

TypeError: Cannot read property 'setState' of null(…)

Thanks

You cannot "add" arrays together. Use the array.concat function ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat ) to concatenate both arrays into one and then set that as the state.

componentWillMount() {

   // Make a request for vehicle data

   axios.all([
     axios.get('/api/seat/models'),
     axios.get('/api/volkswagen/models')
   ])
   .then(axios.spread(function (seat, volkswagen) {
     let vehicles = seat.data.concat(volkswagen.data);
     this.setState({ vehicles: vehicles })
   }))
   //.then(response => this.setState({ vehicles: response.data }))
   .catch(error => console.log(error));

}

There are two issues with this:

1) In your .then "this" is undefined, so you'll need to store a reference to this at the top layer.

2) As the other answer stated, you can't add arrays together in JS like that and need to use concat, although since they're server responses I'd add a default as well to stop it erroring if either of those don't actually return you something.

All together I think it should look like:

componentWillMount() {

  // Make a request for vehicle data
  var that = this;
  axios.all([
    axios.get('/api/seat/models'),
    axios.get('/api/volkswagen/models')
  ])
  .then(axios.spread(function (seat, volkswagen) {
    var seatData = seat.data || [];
    var volkswagenData = volkswagen.data || [];
    var vehicles = seatData.concat(volkswagenData);
    that.setState({ vehicles: vehicles })
  }))
  .catch(error => console.log(error));
}

I want to mention something different. According to the react life cycle, you should prefer call api in componentDidMount() method.

"componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request."

https://reactjs.org/docs/react-component.html#componentdidmount

constructor(){
        super();
        this.state = {};
    }

    componentDidMount(){
        axios.all([
            axios.post('http://localhost:1234/api/widget/getfuel'),
            axios.post('http://localhost:1234/api/widget/getdatarate')
        ])
            .then(axios.spread((fuel,datarate) => {
                this.setState({
                    fuel:fuel.data.data[0].fuel,
                    datarate:datarate.data.data[0].data
                })
            console.log(this.state.fuel)
            console.log(this.state.datarate)

            }))
    }

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