title: React has detected a change in the order of Hooks called, but I can't see any hooks being called conditonally
body: <p>I am using</p>
  <ul>
  <li>ReactJS 16.14.0</li>
  </ul>
  <p>I have a React functional component that relies on data stored in context to render correctly, some of this data needs additional processing before display and some additional data needs fetching. the component is throwing the <strong>React has detected a change in the order of Hooks</strong> error, I have read the react docs on the rules of hooks as well as having a good look through SO but I can't work out why I get the error. I have shortened the code below to keep it brief.</p>
  <pre><code>
      const { enqueueSnackbar } = useSnackbar();
      const [ mainContact, setMainContact ] = useState(undefined);
      const [ mainAddress, setMainAddress ] = useState(undefined);
      const [ thisLoading, setThisLoading ] = useState(true);
      const { organisation, addresses, loading } = useProfileState();
  
  
      useEffect(() =&gt; {
          setThisLoading(true);
          if(organisation &amp;&amp; addresses &amp;&amp; !loading) {
              Promise.all([getMainContact(), getMainAddress()])
              .then(() =&gt; {
                  setThisLoading(false);
              })
              .catch(() =&gt; {
                  console.log(&quot;Failed getting address/contact info&quot;);
                  setThisLoading(false);
              })
          }
      }, [organisation, addresses, loading])
  
  
      const getMainContact = () =&gt; {
          return new Promise((resolve, reject) =&gt; {
              apiService.getData(`/organisation/users/${organisation.mainContact}`)
              .then(mainContact =&gt; {
                  setMainContact(mainContact);
                  return resolve();
              })
              .catch(error =&gt; {
                  enqueueSnackbar(error, { variant: 'error' });
                  return reject();
              })
          })
      }
  
      const getMainAddress = () =&gt; {
          return new Promise((resolve, reject) =&gt; {
              let mainAddress = addresses.find(addr =&gt; addr.id === organisation.mainAddress)
              if(mainAddress !== undefined) {
                  setMainAddress(mainAddress);
                  return resolve();
              } else {
                  enqueueSnackbar(&quot;Error getting main address &quot;, { variant: 'error' });
                  return reject();
              }
          })
      }
  }
  </code></pre>
  <p>I just want to understand why I get this error and any potential solutions or what I am doing wrong etc. below is the full error. If I comment out the <code>setThisLoading(false)</code> in the <code>.then()</code> of the <code>Promise.all()</code> the error goes away but my page never displays any content because I use <code>thisLoading</code> to conditionally render a loading wheel or the content.</p>
  <pre><code>   ------------------------------------------------------
  1. useContext                 useContext
  2. useDebugValue              useDebugValue
  3. useContext                 useContext
  4. useRef                     useRef
  5. useRef                     useRef
  6. useRef                     useRef
  7. useMemo                    useMemo
  8. useEffect                  useEffect
  9. useEffect                  useEffect
  10. useDebugValue             useDebugValue
  11. useContext                useContext
  12. useState                  useState
  13. useState                  useState
  14. useState                  useState
  15. useState                  useState
  16. useState                  useState
  17. useState                  useState
  18. useState                  useState
  19. useContext                useContext
  20. useEffect                 useEffect
  21. undefined                 useContext
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  </code></pre>
  <p>I am just looking to understand why the <code>setThisLoading(false)</code> causes me to get this error.</p>
  <h2>Update</h2>
  <p>The <code>useSnackbar()</code> hook is provided by an external libary notistack
  <a href="https://github.com/iamhosseindhv/notistack" rel="nofollow noreferrer">https://github.com/iamhosseindhv/notistack</a></p>
  <p>Below is the code relating to <code>useProfileState()</code></p>
  <pre><code>import React, { createContext, useContext, useReducer } from 'react';
  
  const initialState = { loggedIn: false, loading: true, error: false }
  
  const ProfileStateContext = createContext();
  const ProfileDispatchContext = createContext();
  
  const ProfileReducer = (state, action) =&gt; {
      switch (action.type) {
          case 'LOGGED_IN':
              console.log(&quot;PROFILE CONTEXT - Logged in&quot;);
              return { ...state, loggedIn: true }
          case 'LOADED':
              console.log(&quot;PROFILE CONTEXT - Data loaded&quot;);
              return { ...state, loading: false, error: false }
          case 'LOADING':
              console.log(&quot;PROFILE CONTEXT - Data loading&quot;);
              return { ...state, loading: true, error: false }
          case 'ERROR':
              console.log(&quot;PROFILE CONTEXT - Error&quot;);
              return { ...state, loading: false, error: true }
          case 'ADD_USER':
              console.log(&quot;PROFILE CONTEXT - Adding user...&quot;);
              return { ...state, user: { ...action.payload } }
          case 'ADD_ORGANISATION':
              console.log(&quot;PROFILE CONTEXT - Adding organisation...&quot;);
              return { ...state, organisation: { ...action.payload } }
          case 'ADD_ROLES':
              console.log(&quot;PROFILE CONTEXT - Adding roles...&quot;);
              return { ...state, roles: [...action.payload] }
          case 'ADD_ORGANISATIONS':
              console.log(&quot;PROFILE CONTEXT - Adding organisations...&quot;);
              return { ...state, organisations: [...action.payload] }
          case 'ADD_ADDRESSES':
              console.log(&quot;PROFILE CONTEXT - Adding addresses...&quot;);
              return { ...state, addresses: [...action.payload] }
          case 'LOGOUT':
              console.log(&quot;PROFILE CONTEXT - Removing context data...&quot;);
              return initialState;
          default:
              console.error(`Unhandled action dispatched to user reducer, action type was: ${action.type}`);
              return state;
      }
  }
  
  const ProfileProvider = ({ children }) =&gt; {
  
      const [state, dispatch] = useReducer(ProfileReducer, initialState)
  
      return (
          &lt;ProfileStateContext.Provider value={state}&gt;
              &lt;ProfileDispatchContext.Provider value={dispatch}&gt;
                  {children}
              &lt;/ProfileDispatchContext.Provider&gt;
          &lt;/ProfileStateContext.Provider&gt;
      );
  };
  
  const useProfileState = () =&gt; {
      const context = useContext(ProfileStateContext);
  
      if (context === undefined) {
          throw new Error('useProfileState must be used within a ProfileContextProvider')
      }
  
      return context;
  };
  
  const useProfileDispatch = () =&gt; {
      const context = useContext(ProfileDispatchContext);
  
      if (context === undefined) {
          throw new Error('useProfileDispatch must be used within a ProfileContextProvider')
      }
  
      return context;
  };
  
  export {
      ProfileProvider,
      useProfileDispatch,
      useProfileState
  }
  </code></pre>
  <h2>Update 2</h2>
  <p>I have also tried chaining the promises and adding a dummy cleanup func as suggested, I still get the same error.</p>
  <pre><code>useEffect(() =&gt; {
      setThisLoading(true);
      if(organisation &amp;&amp; addresses &amp;&amp; !loading) {
          getMainContact()
              .then(() =&gt; {
                  getMainAddress()
                      .then(() =&gt; {
                          getBillingContact()
                              .then(() =&gt; {
                                  getBillingAddress()
                                      .then(() =&gt; {
                                          setThisLoading(false);
                                      })
                              })
                      })
              })
      }
  
      return () =&gt; {};
  }, [organisation, addresses, loading])
  </code></pre>