title: Why is useReducer's dispatch causing re-renders?
body: <p>Suppose I implement a simple global loading state like this:</p>
  
  <pre class="lang-js prettyprint-override"><code>// hooks/useLoading.js
  import React, { createContext, useContext, useReducer } from 'react';
  
  const Context = createContext();
  
  const { Provider } = Context;
  
  const initialState = {
    isLoading: false,
  };
  
  function reducer(state, action) {
    switch (action.type) {
      case 'SET_LOADING_ON': {
        return {
          ...state,
          isLoading: true,
        };
      }
      case 'SET_LOADING_OFF': {
        return {
          ...state,
          isLoading: false,
        };
      }
    }
  }
  
  export const actionCreators = {
    setLoadingOn: () =&gt; ({
      type: 'SET_LOADING_ON',
    }),
    setLoadingOff: () =&gt; ({
      type: 'SET_LOADING_OFF',
    }),
  };
  
  export const LoadingProvider = ({ children }) =&gt; {
    const [{ isLoading }, dispatch] = useReducer(reducer, initialState);
    return &lt;Provider value={{ isLoading, dispatch }}&gt;{children}&lt;/Provider&gt;;
  };
  
  export default () =&gt; useContext(Context);
  
  </code></pre>
  
  <p>Then suppose I have a component that mutates the loading state, but never consumes it, like this:</p>
  
  <pre class="lang-js prettyprint-override"><code>import React from 'react';
  import useLoading, { actionCreators } from 'hooks/useLoading';
  
  export default () =&gt; {
    const { dispatch } = useLoading();
    dispatch(actionCreators.setLoadingOn();
    doSomethingAsync().then(() =&gt; dispatch(actionCreators.setLoadingOff()))
    return &lt;React.Fragment /&gt;;
  };
  
  </code></pre>
  
  <p>According to useReducer docs, dispatch is has a stable identity. I interpreted this to mean that when a component extracts dispatch from a useReducer, it won't re-render when the state connected to that dispatch changes, because the reference to dispatch will always be the same. Basically, dispatch can "treated like a static value".</p>
  
  <p>Yet when this code runs, the line <code>dispatch(actionCreators.setLoadingOn())</code> triggers an update to global state and the <code>useLoading</code> hook is ran again and so is <code>dispatch(actionCreators.setLoadingOn())</code> <strong>(infinite re-renders -_-)</strong></p>
  
  <p>Am I not understanding useReducer correctly? Or is there something else I'm doing that might be causing the infinite re-renders?</p>