UNPKG

@tanstack/react-router

Version:

Modern and scalable routing for React applications

104 lines (103 loc) 3.17 kB
import { useLayoutEffect, usePrevious } from "./utils.js"; import { useRouter } from "./useRouter.js"; import { getLocationChangeInfo, handleHashScroll, trimPathRight } from "@tanstack/router-core"; import * as React$1 from "react"; import { batch, useStore } from "@tanstack/react-store"; //#region src/Transitioner.tsx function Transitioner() { const router = useRouter(); const mountLoadForRouter = React$1.useRef({ router, mounted: false }); const [isTransitioning, setIsTransitioning] = React$1.useState(false); const isLoading = useStore(router.stores.isLoading, (value) => value); const hasPendingMatches = useStore(router.stores.hasPendingMatches, (value) => value); const previousIsLoading = usePrevious(isLoading); const isAnyPending = isLoading || isTransitioning || hasPendingMatches; const previousIsAnyPending = usePrevious(isAnyPending); const isPagePending = isLoading || hasPendingMatches; const previousIsPagePending = usePrevious(isPagePending); router.startTransition = (fn) => { setIsTransitioning(true); React$1.startTransition(() => { fn(); setIsTransitioning(false); }); }; React$1.useEffect(() => { const unsub = router.history.subscribe(router.load); const nextLocation = router.buildLocation({ to: router.latestLocation.pathname, search: true, params: true, hash: true, state: true, _includeValidateSearch: true }); if (trimPathRight(router.latestLocation.publicHref) !== trimPathRight(nextLocation.publicHref)) router.commitLocation({ ...nextLocation, replace: true }); return () => { unsub(); }; }, [router, router.history]); useLayoutEffect(() => { if (typeof window !== "undefined" && router.ssr || mountLoadForRouter.current.router === router && mountLoadForRouter.current.mounted) return; mountLoadForRouter.current = { router, mounted: true }; const tryLoad = async () => { try { await router.load(); } catch (err) { console.error(err); } }; tryLoad(); }, [router]); useLayoutEffect(() => { if (previousIsLoading && !isLoading) router.emit({ type: "onLoad", ...getLocationChangeInfo(router.stores.location.state, router.stores.resolvedLocation.state) }); }, [ previousIsLoading, router, isLoading ]); useLayoutEffect(() => { if (previousIsPagePending && !isPagePending) router.emit({ type: "onBeforeRouteMount", ...getLocationChangeInfo(router.stores.location.state, router.stores.resolvedLocation.state) }); }, [ isPagePending, previousIsPagePending, router ]); useLayoutEffect(() => { if (previousIsAnyPending && !isAnyPending) { const changeInfo = getLocationChangeInfo(router.stores.location.state, router.stores.resolvedLocation.state); router.emit({ type: "onResolved", ...changeInfo }); batch(() => { router.stores.status.setState(() => "idle"); router.stores.resolvedLocation.setState(() => router.stores.location.state); }); if (changeInfo.hrefChanged) handleHashScroll(router); } }, [ isAnyPending, previousIsAnyPending, router ]); return null; } //#endregion export { Transitioner }; //# sourceMappingURL=Transitioner.js.map