UNPKG

react-navplus

Version:

A flexible, performance-optimized navigation link component for React with multi-router support, prefetching, and advanced active state detection

83 lines 2.96 kB
import { useState, useCallback, useRef, useEffect } from 'react'; import { normalizePrefetchOptions, executePrefetch } from '../utils/prefetch'; /** * Hook for handling prefetching of link targets with timeout management * * @param {string} to - The URL to prefetch * @param {object} options - Options for prefetching * @param {boolean | PrefetchOptions} options.prefetch - Prefetch configuration * @param {boolean} options.isExternal - Whether the URL is external * @param {boolean} options.redirection - Whether redirection is enabled * @param {boolean} options.disabled - Whether the link is disabled * @param {any} options.routerContext - Router context for accessing router instance * @returns {object} - Prefetch state and handlers * * @example * // Basic usage * const { isPrefetched, handlePrefetch } = usePrefetch('/dashboard', { * prefetch: true, * isExternal: false * }); * * // When mouse enters the link * const handleMouseEnter = () => { * handlePrefetch(); * }; */ export function usePrefetch(to, options = {}) { const { prefetch = false, isExternal = false, redirection = true, disabled = false, routerContext } = options; // Track if the resource has already been prefetched const [isPrefetched, setIsPrefetched] = useState(false); // Ref for prefetch timeout const prefetchTimeoutRef = useRef(null); // Normalize prefetch options const prefetchOptions = normalizePrefetchOptions(prefetch); // Clean up timeout when unmounting useEffect(() => { return () => { if (prefetchTimeoutRef.current) { clearTimeout(prefetchTimeoutRef.current); } }; }, []); /** * Handle prefetching of the link's target */ const handlePrefetch = useCallback(() => { if (!prefetchOptions.enabled || isExternal || !redirection || disabled || isPrefetched) return; // Clear any existing prefetch timeout if (prefetchTimeoutRef.current) { clearTimeout(prefetchTimeoutRef.current); } // Set a new prefetch timeout prefetchTimeoutRef.current = setTimeout(() => { const success = executePrefetch(to, prefetchOptions.routerType || 'react-router', isExternal, routerContext, prefetchOptions.customPrefetch); if (success) { setIsPrefetched(true); } }, prefetchOptions.delay || 200); }, [ prefetchOptions, to, isExternal, redirection, disabled, isPrefetched, routerContext ]); /** * Cancel prefetching (e.g., on mouse leave) */ const cancelPrefetch = useCallback(() => { if (prefetchTimeoutRef.current) { clearTimeout(prefetchTimeoutRef.current); } }, []); return { isPrefetched, handlePrefetch, cancelPrefetch }; } //# sourceMappingURL=usePrefetch.js.map