0

I am trying to setState of a boolean isLoading variable and using that to show a css loader on top of my component. So what I did was :

  • when I click on a button I setState the isLoading variable from false to true and execute my async function.

  • After the async finishes I just set the isLoading to false using setState()

my problem is that when I first set the isLoading variable to true it doesn't get set and the component does reRender without changing the state ( I even console log the state of that variable on the render function )

I did use the callback function as demonstrated below and still no use.

my code :

  async sendEmail({to,from,subject,html,text}){
    this.setState({
      isEmailLoading:true
    },()=>{
      emailRequests.SendAnEmail({
        to:to,
        text:text,
        subject:subject,
        html:html,
        from:from
      }).then((data)=>{
        this.setState({
           isEmailLoading:false,
         });
        toaster.success({
          title:"Email sent",
          text:"Your email was sent to "+to,
        });
        console.log(data);
      }).catch((error)=>{
        this.setState({
          isEmailLoading:false,
        });
        console.error(error);
        toaster.error({
          title:"Email not sent",
          text:"check console for more information",
        });
      })
    })

  }

my state :

this.state={
      email:{
        to:"",
        subject:"",
        from:"",
        html:"",
        text:""
      },
      isEmailLoading:false,
      isEmailError:false,
      isEmailSuccess:false,
      rawtext:""
    }

Please help this is absolutely not normal.

FIX :

This is very weird and I couldn't debug it, but it turned out that I am using a third party button component that when clicked on, doesn't change state no matter what happens.

Just switching that component to an other button component worked perfectly.

Kaki Master Of Time
  • 1,428
  • 1
  • 21
  • 39
  • do one ting, before the async call `async sendEmail({to,from,subject,html,text}){}`, you call `setState({})` and set loading true and on after async success or failure, setState again to false and check – Akhil Aravind Aug 08 '19 at 09:06
  • 2
    Perhaps try moving the async code out of the setState callback, so go ahead and `setState({ isEmailLoading: true });`, but then after that `await emailRequests.sendemail(...` and in maybe the `finally` block of the promise chain set the loading state back to false, this way it happens whether or not the send email call was successful. – Drew Reese Aug 08 '19 at 09:11
  • @AkhilAravind and Drew Reese, I had exactly that situation before except for the finally block thing which doesn't really have an effect since the state doesn't really change to begin with, but I'll try it anyways and report back. EDIT : Same Thing, nothing changes in the state. – Kaki Master Of Time Aug 08 '19 at 09:58
  • @KakiMasterOfTime see the link, this might help you https://stackoverflow.com/questions/43370176/using-async-setstate?answertab=active#tab-top – Akhil Aravind Aug 08 '19 at 10:14
  • @AkhilAravind That answer is exactly what my OG post has as code, setting the sendingEmail in the callback to be sure that the isEmailLoading is equal to true. it doesn't work at all. – Kaki Master Of Time Aug 08 '19 at 10:16
  • Just out of curiosity do you mind sharing the old code with the button that didn't work? I'd be a little surprised to find a button component in the wild that didn't call some click/press handler. – Drew Reese Aug 08 '19 at 14:58

0 Answers0