我最近才开始了解 Lisp 上下文中的宏是什么。我的理解是,基本上,代码分两遍执行。在第一遍中,解释器识别对宏的调用并用它们的返回值替换它们。第二个,它正常执行代码。
这看起来就像 React 中自定义钩子所发生的情况。例如,如果您有 useOnlineStatus
挂钩:
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; }
这就像一个宏。如果您像这样使用 useOnlineStatus
挂钩:
const isOnline = useOnlineStatus();
这就像对宏的调用。所以如果你有:
function StatusBar() { const isOnline = useOnlineStatus(); return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>; }
第一次通过后,它被转换成:
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>; }
然后在第二遍时它会正常执行。这是自定义钩子发生情况的准确模型吗?
如果你眯着眼睛看的话,情况有点像那样,但有几点:
虽然浏览器确实会执行多次传递来解析然后执行 JavaScript,但调用挂钩并不是这样的示例。因此,运行该组件只需一次传递,逐行运行,并在遇到该指令时单步执行该函数。
相同的思维模型可以应用于每个函数调用。当您致电时:
您可以将其视为解压 Math.max 中的代码并将其放入您的主函数中。但实际上它并不是这样做的。