title: Executing async code on update of state with react-hooks
body: <p>I have something like: </p>
  
  <pre><code>const [loading, setLoading] = useState(false);
  
  ...
  
  setLoading(true);
  doSomething(); // &lt;--- when here, loading is still false. 
  </code></pre>
  
  <p>Setting state is still async, so what's the best way to wait for this <code>setLoading()</code> call to be finished?</p>
  
  <p>The <code>setLoading()</code> doesn't seem to accept a callback like <code>setState()</code> used to. </p>
  
  <h2>an example</h2>
  
  <h3>class-based</h3>
  
  <pre><code>getNextPage = () =&gt; {
      // This will scroll back to the top, and also trigger the prefetch for the next page on the way up.
      goToTop();
  
      if (this.state.pagesSeen.includes(this.state.page + 1)) {
        return this.setState({
          page: this.state.page + 1,
        });
      }
  
      if (this.state.prefetchedOrders) {
        const allOrders = this.state.orders.concat(this.state.prefetchedOrders);
        return this.setState({
          orders: allOrders,
          page: this.state.page + 1,
          pagesSeen: [...this.state.pagesSeen, this.state.page + 1],
          prefetchedOrders: null,
        });
      }
  
      this.setState(
        {
          isLoading: true,
        },
        () =&gt; {
          getOrders({
            page: this.state.page + 1,
            query: this.state.query,
            held: this.state.holdMode,
            statuses: filterMap[this.state.filterBy],
          })
            .then((o) =&gt; {
              const { orders } = o.data;
              const allOrders = this.state.orders.concat(orders);
              this.setState({
                orders: allOrders,
                isLoading: false,
                page: this.state.page + 1,
                pagesSeen: [...this.state.pagesSeen, this.state.page + 1],
                // Just in case we're in the middle of a prefetch.
                prefetchedOrders: null,
              });
            })
            .catch(e =&gt; console.error(e.message));
        },
      );
    };
  </code></pre>
  
  <h3>convert to function-based</h3>
  
  <pre><code>  const getNextPage = () =&gt; {
      // This will scroll back to the top, and also trigger the prefetch for the next page on the way up.
      goToTop();
  
      if (pagesSeen.includes(page + 1)) {
        return setPage(page + 1);
      }
  
      if (prefetchedOrders) {
        const allOrders = orders.concat(prefetchedOrders);
        setOrders(allOrders);
        setPage(page + 1);
        setPagesSeen([...pagesSeen, page + 1]);
        setPrefetchedOrders(null);
        return;
      }
  
      setIsLoading(true);
  
      getOrders({
        page: page + 1,
        query: localQuery,
        held: localHoldMode,
        statuses: filterMap[filterBy],
      })
        .then((o) =&gt; {
          const { orders: fetchedOrders } = o.data;
          const allOrders = orders.concat(fetchedOrders);
  
          setOrders(allOrders);
          setPage(page + 1);
          setPagesSeen([...pagesSeen, page + 1]);
          setPrefetchedOrders(null);
          setIsLoading(false);
        })
        .catch(e =&gt; console.error(e.message));
    };
  </code></pre>
  
  <p>In the above, we want to run each setWhatever call sequentially. Does this mean we need to set up many different useEffect hooks to replicate this behavior? </p>