title: Asynchronously updating state using reducer from api call
body: <p>I am trying to initialize my app data from an api inside a react reducer. The api calls, and dispatch is called on the reducer, but when the function component re-renders, it is still using the initial state.</p>
  
  <p>Here is the relevant code:</p>
  
  <p>Ui.js</p>
  
  <pre class="lang-js prettyprint-override"><code>import { useReducer } from 'react';
  import api from './api';
  
  
  const reducer = (state: Object, action: {type: string, data: Object}) =&gt; {
    switch (action.type) {
      case 'init':
        return action.data;
    }
  };
  
  class Ui {
    constructor(schematicId) {
      const initialState = {loadingStatus: 'Loading...'};
      [this.state, this.dispatch] = useReducer(reducer, initialState);
  
      this.schematicId = schematicId;
      api.init(schematicId).then(data =&gt; {
        this.dispatch({type: 'init', data: data});
      });
    }
  }
  
  export default Ui;
  </code></pre>
  
  <p>index.js</p>
  
  <pre><code>let alertStore;
  let ui;
  const App = props =&gt; {
    alertStore = alertStore || new AlertStore();
    ui = ui || new Ui(props.schematicId);
  
    return (
      &lt;div className="container-fluid"&gt;
        {alertStore.alerts.map((a, index) =&gt; (
          &lt;Alert dismissible key={index}
            onClose={() =&gt; alerts.remove(index)}
            variant={a.variant}&gt;{a.msg}&lt;/Alert&gt;
        ))}
        &lt;LoadingBoundary status={ui.state.loadingStatus}&gt;
          ...
        &lt;/LoadingBoundary&gt;
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p>I originally just had</p>
  
  <pre><code>alertStore = new AlertStore();
  ui = new Ui(schematicId);
  </code></pre>
  
  <p>but it caused the web page to freeze. I think something in the Ui.js file caused an infinite loop before changing it to</p>
  
  <pre><code>  alertStore = alertStore || new AlertStore();
    ui = ui || new Ui(props.schematicId);
  </code></pre>
  
  <p>because I have used <code>alertStore = new AlertStore();</code> before without problems in a different app.</p>
  
  <p>I've put breakpoints in index.js and Ui.js. index.js is re-rendered after the switch statement in Ui.js, but the state is still {loadingStatus: 'Loading...'} instead of the state returned from the api.</p>