jason
jason

Reputation: 612

ReactJS - waiting for multiple setState to complete before executing next code

I am working with ReactJS, and ran into a problem. I used setState multiple times after getting my response.data from axios in order to set all the neccessary data into my state. However, the issue is that I want to wait for all the setStates to finish before moving on to the next line of code. I am not sure how to do that, as I know that the setState takes in a second callback function, but thats only for a single setState. I tried looking into Promise but I am not sure how to implement that correctly.

Here is my code:

axiosInstance.get(`/customer-converted/?group=department&metric=${metric}&start=${start}&end=${end}`)
    .then(response => {
        this.setState({ data: response.data });
        let rangeStart = (response.data.length > 3) ? response.data[response.data.length - 3].date : response.data[0].date
        let rangeEnd = response.data[response.data.length - 1].date
        this.setState({ start: rangeStart })
        this.setState({ end: rangeEnd })
        // execute next line of code here only after all setState above are finished
    })

All help is appreciated, thanks all!

Upvotes: 0

Views: 430

Answers (4)

andy mccullough
andy mccullough

Reputation: 9601

I would tend to lean towards a different paradigm than relying on the setState callback as mentioned by others, for the reasons outlined here - What is the advantage of using componentDidUpdate over the setState callback?

Using a more modern version of React, and using hooks, you can achieve a much more 'reactive' programming styling using useEffect to react to state updates.

Upvotes: -1

Ehsan Nazeri
Ehsan Nazeri

Reputation: 801

try this one it might help you

axiosInstance.get(`/customer-converted/?group=department&metric=${metric}&start=${start}&end=${end}`)
    .then(response => {
        this.setState({ data: response.data });
        let rangeStart = (response.data.length > 3) ? response.data[response.data.length - 3].date : response.data[0].date
        let rangeEnd = response.data[response.data.length - 1].date
        this.setState({ start: rangeStart })
        this.setState({ end: rangeEnd })
        return response
    }).then((response)=>{
// execute next line of code here 
});

Upvotes: -1

ehab
ehab

Reputation: 8064

the setState method takes a second argument, which is a callback that will be executed once state is updated.

axiosInstance.get(`/customer-converted/?group=department&metric=${metric}&start=${start}&end=${end}`)
    .then(response => {

        let rangeStart = (response.data.length > 3) ? response.data[response.data.length - 3].date : response.data[0].date
        let rangeEnd = response.data[response.data.length - 1].date
         // also you should combine state updates together
         this.setState({ data: response.data, start: rangeStart, end: rangeEnd  }, () => console.log('state was updated'));

        // execute next line of code here only after all setState above are finished
    })

Upvotes: 0

Red Baron
Red Baron

Reputation: 7682

you can set multiple things at the same time like so:

this.setState({ start: rangeStart, end: rangeEnd })

you can also use a callback within setState to do something after the state has been set

this.setState({
    start: rangeStart, 
},() => {
    console.log('you can do something else here after you set state');
});

Upvotes: 3

Related Questions