title: How do I implement a loading spinner on form submit with react-redux?
body: <p>I have a form in my React application that passes the form data to an action creator and then to my redux reducer on submit. I would like a loading spinner to show inside the submit button when it is clicked and then be removed when the data has been returned. I am confused on how to implement this. I was thinking of keeping the <code>loading : true/false</code> in my redux state but then it wouldn't be changed immediately the submit button is presses since my action isn't dispatched to my reducer until it has gotten the data back from the backend api with axios. I have also thought about keeping the <code>loading : true/false</code> in the component's state but I feel like that isn't the best way to go about it.</p>
  
  <p>My Component:</p>
  
  <pre><code>class SignUp extends Component{
      state = {
          userdetails : {
              firstname : '',
              lastname : '',
              email : '',
              password : '',
          },
          error_message : '',
          loading : false,
      }
  
  
      handleSubmit = (e) =&gt;{
          e.preventDefault()
          this.setState({loading:true,})
          this.props.signup(this.state.userdetails);
      }
      loadingChecker = () =&gt;{
          switch(this.state.loading){
              case  true:
                  return &lt;div class="loader"&gt;&lt;/div&gt;
              case false:
                  return &lt;p&gt;Login&lt;/p&gt;
  
          }
      }
      render(){
          return(
              &lt;div className="signup"&gt;
                      &lt;div className="left col-sm-12 col-lg-6 d-none d-lg-block"&gt;&lt;/div&gt;
                      &lt;div className="right col-sm-12 col-lg-6"&gt;
                          &lt;div className="rightinner col-sm-12 col-lg-8"&gt;
                              &lt;p className="signupheader"&gt;&lt;/p&gt;
                              &lt;p className="signupsubheader"&gt;&lt;/p&gt;
                              &lt;p&gt;{this.props.token}&lt;/p&gt;
                              &lt;form onSubmit={this.handleSubmit}&gt;
                                  &lt;input className="inputs" id="firstname" type="text" placeholder="First Name" onKeyUp={this.handleUpdate}/&gt;
                                  &lt;input className="inputs" id="lastname" type="text" placeholder="Last Name" onKeyUp={this.handleUpdate}/&gt;
                                  &lt;input className="inputs" id="email"type="text" placeholder="Email" onKeyUp={this.handleUpdate}/&gt;
                                  &lt;input className="inputs" id="" type="text" placeholder onKeyUp={this.handleUpdate}/&gt;
                                  &lt;input type="password" name="" id="password" className="inputs" placeholder="Password" onKeyUp={this.handleUpdate}/&gt;
                                  &lt;p className="error_message"&gt;{this.state.error_message}&lt;/p&gt;
                                  &lt;p className="error_message"&gt;{this.props.error_message}&lt;/p&gt;
                                  &lt;button type="submit" className="submit" disabled&gt;{this.loadingChecker()}&lt;/button&gt;
                                  &lt;p className="alreadysignedup"&gt;Already have an account? &lt;Link to="/login"&gt;Login&lt;/Link&gt;&lt;/p&gt;
                              &lt;/form&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
              &lt;/div&gt;
          )
      }
  }
  const mapStateToProps = (state) =&gt;{
      return{
          error_message : state.signup.userdetails.error_message,
          first_name : state.signup.userdetails.first_name,
          last_name : state.signup.userdetails.last_name,
          email : state.signup.userdetails.email,
          token : state.signup.userdetails.token,
          loading : state.signup.loading,
      }
  }
  const mapDispatchToProps = (dispatch) =&gt;{
      return{
          signup : (details) =&gt; dispatch(signUpAction(details))
      }
  }
  export default connect(mapStateToProps,mapDispatchToProps)(SignUp);
  </code></pre>
  
  <p>My action:</p>
  
  <pre><code>import axios from 'axios';
  
  export const signUpAction = (details) =&gt;{
      return( dispatch, getState ) =&gt; {
          axios.post('http://127.0.0.1:8000/signup',details)
              .then(resp =&gt; {dispatch({type:'SIGNUP', payload:resp.data})})
          // dispatch({type:'SIGNUP', payload:details,})
      }
  };
  </code></pre>
  
  <p>My reducer:</p>
  
  <pre><code>const initState = {
      userdetails : {
          firstname : '',
          email : '',
          lastname : '',
          token : '',
      },
      error_message : '',
  }
  
  const signUpReducer = (state = initState, action) =&gt;{
      switch(action.type){
          case 'SIGNUP':
              if(action.payload === "error"){
                  return {...state, error_message:'This email address is alredy being used by another account'};
              }else{
                  console.log(state.userdetails)
                  return {userdetails : {...state.userdetails, firstname:action.payload.firstname, lastname:action.payload.lastname, email:action.payload.email, token:action.payload.token,}};
              }
          case 'LOGIN':
      }
      return state;
  }
  
  export default signUpReducer;
  </code></pre>