title: Using useEffect() Hook and Async/Await to Fetch Data from Firebase/Firestore
body: <h1>1. My Intention:</h1>
  
  <p>Using <strong><em>useEffect()</em></strong> hook to initialize component's state variable from the props, whose data is extracted from firebase using <strong><em>mapStateToProps()</em></strong>.</p>
  
  <hr>
  
  <h1>2. Problem: unable to initialize component's state variable</h1>
  
  <ul>
  <li><p>The idea is that the useEffect will run only once when the component mounts. In this initialization window, I want to load data from firebase to this component's local state variable.  </p></li>
  <li><p>It works fine when <a href="https://www.robinwieruch.de/react-hooks-fetch-data" rel="noreferrer">running the example in this tutorial</a>. In it, he fetches data with axios() in a <strong><em>async/await</em></strong> function.  See below section 3 for his code. </p></li>
  <li><p>But when I do it, trying to fetch data from the props, which is synced with or initialized by Firestore, I kept getting null, unable to retrieve data from the <code>result</code> returned from my async/await function. </p></li>
  <li><p>I think it is because my lack of understanding of async/await.  I wasn't able to create a valid <strong><em>async/await</em></strong> function to retrieve data from props.</p></li>
  </ul>
  
  <h3>Question:</h3>
  
  <p>I suspect that's where the problem lies. So, what's the correct way to write an <strong><em>async/await</em></strong> function which properly retrieve data from the props that was synced with firebase? </p>
  
  <h3>My Problem Code:</h3>
  
  <pre><code>    import React, { useState, useEffect} from "react";
      import { connect } from "react-redux";
      import { firestoreConnect } from "react-redux-firebase";
      import { compose } from "redux";
  
      const app = props =&gt; {
        const { order } = props;  
        const [data, setData] = useState({});
  
        useEffect(() =&gt; {
          const fetchData = async () =&gt; {
            const result = await (() =&gt; {
              return new Promise(resolve =&gt; {
                if (order) { resolve(order); }
              });
            })();
            setData(result);
          };
          fetchData();
        }, []);
        /** if I leave useEffect's second argument empty, which is intended to run only once at the beginning, then i'm getting null  */
  
      ...
  
      const mapStateToProps = state =&gt; {
        const id = "DKA77MC2w3g0ACEy630g"; // docId for testing purpose.
        const orders = state.firestore.data.orders;
        const order = orders ? orders[id] : null;        
        return {
          order: order
        };
      };
  
      export default compose(
        connect(mapStateToProps),
        firestoreConnect([{collection: "orders"}])
      )(app);
  </code></pre>
  
  <hr>
  
  <h2>What I've Tried:</h2>
  
  <ul>
  <li>If I add <strong><em>order</em></strong> into the second argument, then It will correctly load the data into component's state variable.  But it will re-load the props' data into component's state variable and erase any changes in every re-render cycle.</li>
  </ul>
  
  <pre><code> useEffect(() =&gt; {
          ...
        }, [order]);
  </code></pre>
  
  <ul>
  <li>Is <strong><em>mapStateToProps()</em></strong> happens after the initial component mount? Because that'll explain why in the initial effect, props is always empty.</li>
  </ul>
  
  <hr>
  
  <h1>3. Tutorial I was following: fetch data using hooks</h1>
  
  <p>I was able to successfully fetch data using <a href="https://www.robinwieruch.de/react-hooks-fetch-data" rel="noreferrer">techniques from this tutorial</a>: </p>
  
  <pre><code>  const [data, setData] = useState({ hits: [] });
    useEffect(() =&gt; {
      const fetchData = async () =&gt; {
        const result = await axios(
          "https://hn.algolia.com/api/v1/search?query=redux"
        );
        setData(result.data);
      };
      fetchData();
    }, []);
  </code></pre>