Ich habe erst vor kurzem begonnen zu verstehen, was Makros in einem Lisp-Kontext sind. Nach meinem Verst?ndnis wird der Code grunds?tzlich in zwei Durchg?ngen ausgeführt. Im ersten Durchgang identifiziert der Interpreter Aufrufe von Makros und ersetzt sie durch ihre Rückgabewerte. Zweitens führt es den Code normal aus.
Das sieht aus wie das, was mit benutzerdefinierten Hooks in React passiert. Wenn Sie beispielsweise den Haken useOnlineStatus
haben:
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; }
Das ist wie ein Makro. Wenn Sie den useOnlineStatus
-Hook wie folgt verwenden:
const isOnline = useOnlineStatus();
Das ist wie ein Aufruf eines Makros. Wenn Sie also Folgendes haben:
function StatusBar() { const isOnline = useOnlineStatus(); return <h1>{isOnline ? '? Online' : '? Disconnected'}</h1>; }
Nach dem ersten Durchgang wird es umgewandelt in:
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>; }
Dann wird es beim zweiten Durchgang normal ausgeführt. Ist dies ein genaues Modell dessen, was mit benutzerdefinierten Haken passiert?
如果你瞇著眼睛看的話,情況有點像那樣,但有幾點:
雖然瀏覽器確實會執(zhí)行多次傳遞來解析然后執(zhí)行 JavaScript,但調(diào)用掛鉤并不是這樣的示例。因此,運行該組件只需一次傳遞,逐行運行,并在遇到該指令時單步執(zhí)行該函數(shù)。
相同的思維模型可以應(yīng)用于每個函數(shù)調(diào)用。當(dāng)您致電時:
const foo = Math.max(0, 5);
您可以將其視為解壓 Math.max 中的代碼并將其放入您的主函數(shù)中。但實際上它并不是這樣做的。