xdgdeveloper
xdgdeveloper

Reputation: 63

setState not being executed maybe

I have a component that fetches a list of items from an API on a button click. name state variable comes from the input box. Code of my handleSubmit method is:

handleSubmit(event) {
  event.preventDefault()
  this.setState({
    fetching: true
  })    
  fetch("https://example.com/v2/sites/list/"+this.state.name, {
    method: 'GET',
    })
    .then(response => async(response) => { 
    await response.json()
    this.setState({
      names: response.json()["items"],
      fetching: false,
      fetched: true
    })
    toast.success(<NotifySuccess />)
  })
  .catch(error => toast.error(<NotifyFailure />));
}

On fetched state value being set to true, in my render method, i am trying to render a alert box having names value in it through portals but it seems setState is not working as expected. No alert box appears and on inspection of component through React developer tool, fetched state value is not being updated to true. Why is it not being updated? Plus, when i set it to true myself using developer tool, an alert box appears with empty value. I clicked ok to close it but it opens again. Have to press ok button again. So alert box also appears two times. Any help would be appreciated. Thanks.

Upvotes: 0

Views: 63

Answers (2)

Baltasar Solanilla
Baltasar Solanilla

Reputation: 131

@CertainPeformance is absolutely right, just adding a bit of a cleaner approach in case you can make handleSubmit an async function.

async handleSubmit(event) {
...
try {
 const response = await fetch("https://example.com/v2/sites/list/" + 
    this.state.name, {
    method: 'GET',
 })
 const { items } = await response.json()
 this.setState({
     names: items,
     fetching: false,
     fetched: true
 })
 toast.success(<NotifySuccess />)
} catch (error) {
 toast.error(<NotifyFailure />)
};

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371198

The response is a Promise. Awaiting it in one section of the code doesn't transform that same variable into the resolve value. You need to assign the result of awaiting it into a variable, which will hold the resolve value, then pass that to setState:

fetch("https://example.com/v2/sites/list/" + this.state.name, {
    method: 'GET',
})
    .then(response => async (response) => {
        const result = await response.json();
        this.setState({
            names: result.items,
            fetching: false,
            fetched: true
        })
        toast.success(<NotifySuccess />)
    })
    .catch(error => toast.error(<NotifyFailure />));

Upvotes: 1

Related Questions