diff --git a/src/utils/hooks/window-focus.js b/src/utils/hooks/window-focus.js index a221e48ea..0cf5585e4 100644 --- a/src/utils/hooks/window-focus.js +++ b/src/utils/hooks/window-focus.js @@ -1,26 +1,17 @@ -import { useEffect, useState } from "react"; +import { useSyncExternalStore } from "react"; const hasFocus = () => typeof document !== "undefined" && document.hasFocus(); -const useWindowFocus = () => { - const [focused, setFocused] = useState(hasFocus); +const subscribe = (onFocusChange) => { + window.addEventListener("focus", onFocusChange); + window.addEventListener("blur", onFocusChange); - useEffect(() => { - setFocused(hasFocus()); - - const onFocus = () => setFocused(true); - const onBlur = () => setFocused(false); - - window.addEventListener("focus", onFocus); - window.addEventListener("blur", onBlur); - - return () => { - window.removeEventListener("focus", onFocus); - window.removeEventListener("blur", onBlur); - }; - }, []); - - return focused; + return () => { + window.removeEventListener("focus", onFocusChange); + window.removeEventListener("blur", onFocusChange); + }; }; +const useWindowFocus = () => useSyncExternalStore(subscribe, hasFocus, () => false); + export default useWindowFocus; diff --git a/src/utils/hooks/window-focus.test.jsx b/src/utils/hooks/window-focus.test.jsx index 818fb15fe..2491c39e9 100644 --- a/src/utils/hooks/window-focus.test.jsx +++ b/src/utils/hooks/window-focus.test.jsx @@ -12,15 +12,17 @@ function Fixture() { describe("utils/hooks/window-focus", () => { it("tracks focus/blur events", async () => { - vi.spyOn(document, "hasFocus").mockReturnValue(true); + const hasFocus = vi.spyOn(document, "hasFocus").mockReturnValue(true); render(); expect(screen.getByTestId("focused")).toHaveTextContent("true"); + hasFocus.mockReturnValue(false); window.dispatchEvent(new Event("blur")); await waitFor(() => expect(screen.getByTestId("focused")).toHaveTextContent("false")); + hasFocus.mockReturnValue(true); window.dispatchEvent(new Event("focus")); await waitFor(() => expect(screen.getByTestId("focused")).toHaveTextContent("true")); });