import { Link } from 'react-router-dom'
import { useQueryClient } from '@tanstack/react-query'
import api from '@/services/api'
import { PostId } from '@/types'
interface PostLinkProps {
postId: PostId
children: React.ReactNode
}
export function PostLink({ postId, children }: PostLinkProps) {
const queryClient = useQueryClient()
let prefetchTimeout: NodeJS.Timeout
const prefetchPost = () => {
prefetchTimeout = setTimeout(() => {
queryClient.prefetchQuery({
queryKey: ['posts', postId],
queryFn: () => api.get(`/posts/${postId}`).then((res) => res.data),
staleTime: 5 * 60 * 1000, // Consider fresh for 5 minutes
})
}, 100) // Small delay to avoid prefetching during quick mouseovers
}
const cancelPrefetch = () => {
if (prefetchTimeout) {
clearTimeout(prefetchTimeout)
}
}
return (
<Link
to={`/posts/${postId}`}
onMouseEnter={prefetchPost}
onMouseLeave={cancelPrefetch}
className="text-blue-600 hover:underline"
>
{children}
</Link>
)
}
Prefetching data when users hover over links makes navigation feel instant. React Query's prefetchQuery loads data into cache before users click. When they navigate, the data is already available and renders immediately. I use the onMouseEnter event on links to trigger prefetching, with a small delay to avoid unnecessary requests when users quickly mouse over links. This technique works best for detail pages or frequently accessed routes. The cache ensures prefetched data doesn't go to waste if users don't navigate—it's available for subsequent visits. Combined with React Router, this creates an experience that rivals native apps.