title: Memoize dependencies within a custom react hook is anti-pattern?
body: <p>I'm encounter myself writing a <strong>custom hook that exposes a socket connection</strong>, the fact is that the code is there and it is working but I have the following API.</p>
  
  <pre><code>const socket = useWebSocket(
    companyId,
    accessToken,
    resourceUrl,
    !settings.data.manualDispatch,
    options
  );
  </code></pre>
  
  <p>The hook encapsulate several things:</p>
  
  <ol>
  <li>Authenticate the WebSocket connection by asking first for a ticket that is appended to the WebSocket url <em>(so it actually does a first HTTP request that returns a ticket and then trigger other effect that create a connection and update the socket state that is being return)</em></li>
  <li>As I mentioned previously it does a request GET to a ticket and create a WebSocket connection</li>
  <li>Cleanup any existing WebSocket connection when a new one is created <em>(through state management)</em></li>
  </ol>
  
  <p><strong>The problem is:</strong></p>
  
  <p>I am <strong>currently</strong> using a reference within the hook to avoid create new objects and ending up in an infinite loop BUT <strong>It will be that consider an anti-pattern?</strong>.</p>
  
  <p><strong>Use memo alongside the hook?</strong>
  Yes sure is valid approach but I feel like I am forcing the developers using my hook to write the same code over and over <em>(memoize the options before pass it to the hook)</em>.</p>
  
  <p><strong>In summary:</strong></p>
  
  <p><strong>OPTION 1:</strong></p>
  
  <p>Don't memoize the options to use the hook and do that process within the hook (because options are made of things that are not mean to change, urls and callbacks).</p>
  
  <pre><code>   const socket = useWebSocket(
          companyId,
          accessToken,
          resourceUrl,
          !settings.data.manualDispatch,
          {
              onMessageCallback: message =&gt; {
                  // do things with message
              },
              onUnexpectedCloseCallback: () =&gt; {
                  // do things on close
              },
              url: websocketUrl,
          }
      );
  </code></pre>
  
  <p><strong>OPTION 2:</strong></p>
  
  <p>We memoize the options in order to use the hook <strong>because the option 1 is an anti-pattern</strong>.</p>
  
  <pre><code>    const options = useMemo(
          () =&gt; ({
              onMessageCallback: message =&gt; {
                  // do things with message
              },
              onUnexpectedCloseCallback: () =&gt; {
                  // do things on close
              },
              url: websocketUrl,
          }),
          [websocketUrl]
      );
  
      const socket = useWebSocket(
          companyId,
          accessToken,
          resourceUrl,
          !settings.data.manualDispatch,
          options
      );
  </code></pre>