title: UseEffect not fired when redux props change caused by async api call with redux-thunk
body: <p>I have a functional login page connected with redux, I'm firing an async event onSubmit that will trigger the <code>emailLogin</code> action, I am using <code>useEffect</code> to detect the change of the <code>isLoading</code> prop to see whether login finished or not. If login success, the redux store should have the user object, if failed, the user should remain null.</p>
  
  <p>The question is, I know that the login is success, which should triggered the change of <code>isLoading</code>, the parameter that decide whether the <code>useEffect</code>, however, the <code>useEffect</code> is not fired. Also, the <code>console.log('done');</code> after the line <code>await emailLogin(authData);</code> is never fired. Ssomething is wrong.</p>
  
  <pre><code>import React, { useState, useEffect } from 'react';
  import { connect } from 'react-redux';
  import { Link, useHistory } from 'react-router-dom';
  import { emailLogin } from '../actions/index';
  
  function Login({ user, isLoading, emailLogin }) {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const history = useHistory();
  
    useEffect(() =&gt; {
      console.log('useEffect fired', user, isLoading); //&lt;-----This does not fire after login success
      if (user) {
        history.push('/protected_home');
      } 
    }, [isLoading]);
  
    const submitEmailLoginForm = async (e) =&gt; {
      e.preventDefault();
      const authData = { email, password };
      await emailLogin(authData);
      console.log('done'); // &lt;------- This is never fired
    };
  
    return (
      &lt;div&gt;
        &lt;h2&gt;Login&lt;/h2&gt;
        &lt;Link to="/"&gt;back&lt;/Link&gt;
        &lt;form onSubmit={submitEmailLoginForm}&gt;
          &lt;label&gt;
            email:
            &lt;input
              type="text"
              name="email"
              value={email}
              onChange={(e) =&gt; setEmail(e.target.value)}
            /&gt;
          &lt;/label&gt;
          &lt;label&gt;
            password:
            &lt;input
              type="text"
              name="password"
              value={password}
              onChange={(e) =&gt; setPassword(e.target.value)}
            /&gt;
          &lt;/label&gt;
          &lt;input type="submit" value="Submit" /&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    );
  }
  
  const mapStateToProps = (state) =&gt; ({
    user: state.user,
    isLoading: state.isLoading
  });
  
  const mapDispatch = {
    emailLogin: emailLogin
  };
  
  export default connect(mapStateToProps, mapDispatch)(Login);
  </code></pre>
  
  <p>My action file:</p>
  
  <pre><code>import axios from 'axios';
  
  export const authActions = {
    EMAIL_LOGIN_START: '@@EMAIL_LOGIN_START',
    EMAIL_LOGIN_SUCCESS: '@@EMAIL_LOGIN_SUCCESS'
  };
  
  export const emailLogin = ({ email, password }) =&gt; async (dispatch) =&gt; {
    dispatch({ type: authActions.EMAIL_LOGIN_START });
    try {
      const response = await axios.post('http://localhost:5001/api/auth', {
        email: email,
        password: password
      });
      dispatch({
        type: authActions.EMAIL_LOGIN_SUCCESS,
        payload: {
          user: { ...response.data }
        }
      });
    } catch (error) {
      console.log('Should dispatch api error', error.response);
    }
  };
  </code></pre>
  
  <p>My Reducer:</p>
  
  <pre><code>import { authActions } from '../actions/index';
  
  const initialState = {
    user: null,
    isLoading: false
  };
  
  const userReducer = (state = initialState, action) =&gt; {
    switch (action.type) {
      case authActions.EMAIL_LOGIN_START:
        return { ...state, isLoading: true };
      case authActions.EMAIL_LOGIN_SUCCESS:
        console.log('Reducer check =&gt; Login is success'); //&lt;-----this line is printed
        return { ...state, user: action.payload.user, isLoading: false };
      default:
        return state;
    }
  };
  
  export default userReducer;
  </code></pre>
  
  <p>In the reducer, I see that the success action is actually triggered by checking the <code>console.log()</code>. Also in the redux dev tool, I can actually see that the login is success and the <code>isLoading</code> prop has changed :
  <a href="https://i.stack.imgur.com/UHTvR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UHTvR.png" alt="enter image description here"></a></p>