Making sense of React’s useEffect

Today Dan Abramov published an extensive deep dive into useEffect. The issue that many devs (who, including me, have been using componentDidMount before) are having, is that they now need to unlearn a few things

It’s only after I stopped looking at the useEffect Hook through the prism of the familiar class lifecycle methods that everything came together for me.

This reply-tweet made resonated quite well:

The read is really extensive (40+ minutes), but totally worth your time.

~

A few days ago, Adam Rackis has posted a nice example on his blog in which he (re)wrote a component that contains a websocket. As the websocket connection would always be reinitialised with every render, he combined useEffect with useReducer

While we could add every piece of needed state to our useEffect dependency list, this would cause the web socket to be torn down, and re-created on every update.

If we look closer, however, we might notice something interesting. Every operation we’re performing is always in terms of prior state. […] This is precisely where a reducer shines; in fact, sending commands that project prior state to a new state is the whole purpose of a reducer.

const BookEntryList = props => {
  const [state, dispatch] = useReducer(scanReducer, initialState);

  useEffect(() => {
    const ws = new WebSocket(webSocketAddress("/bookEntryWS"));

    ws.onmessage = ({ data }) => {
      let packet = JSON.parse(data);
      dispatch([packet._messageType, packet]);
    };
    return () => {
      try {
        ws.close();
      } catch (e) {}
    };
  }, []);

  //...
};

~

A neat use-case for useEffect, detailed by Sebastian De Deyne, is to reset the page number when the search query changes:

Clever 😊

A Complete Guide to useEffect →
Hooks, State, Closures, and useReducer →

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.