Home  >  Q&A  >  body text

Custom hook (like) macros in React?

I have only recently begun to understand what macros are in a Lisp context. My understanding is that basically, the code is executed in two passes. In the first pass, the interpreter identifies calls to macros and replaces them with their return values. Second, it executes the code normally.

This looks like what happens with custom hooks in React. For example, if you have the useOnlineStatus hook:

function useOnlineStatus() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);
  return isOnline;
}

This is like a macro. If you use the useOnlineStatus hook like this:

const isOnline = useOnlineStatus();

This is like a call to a macro. So if you have:

function StatusBar() {
  const isOnline = useOnlineStatus();
  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

After the first pass, it is converted to:

function StatusBar() {
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function handleOnline() {
      setIsOnline(true);
    }
    function handleOffline() {
      setIsOnline(false);
    }
    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);
    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
}

Then it will execute normally on the second pass. Is this an accurate model of what happens with custom hooks?

P粉393030917P粉393030917222 days ago418

reply all(1)I'll reply

  • P粉647504283

    P粉6475042832024-04-03 09:28:01

    If you squint, it looks a bit like that, but with a few points:

    1. While the browser does perform multiple passes to parse and then execute JavaScript, calling a hook is not an example of this. Therefore, running the component requires only one pass, running line by line, and stepping into the function when the instruction is encountered.

    2. The same mental model can be applied to every function call. When you call:

    const foo = Math.max(0, 5);

    You can think of it as unpacking the code in Math.max and putting it into your main function. But that's not actually how it works.

    reply
    0
  • Cancelreply