Hooks & Links
The Getting Started guide covers the basic shape of Link. This page
covers the hooks it's built from - useful directly whenever the UI you need isn't literally a
<Route>/<a> pair - and Link's fuller surface.
The hooks
jarl-react's hooks are all thin wrappers over useAtom/useAtomValue/useSetAtom for a route
atom, named for what they're for rather than what they do under the hood:
useRoute(routeAtom)- the route's current match state (match,exact,values,reverse). Equivalent touseAtomValue(routeAtom).useIsActive(routeAtom, { exact? })- just the boolean, for nav-highlighting logic that doesn't need the rest of the match state.useHref(routeAtom, values)- reversesvaluesinto a URL string, without a click handler. Useful for a canonical<link>tag, a share URL, or a prefetchhrefthat isn't a nav link.useNavigate(routeAtom)- a stablenavigate(values)function for imperative navigation outside of rendering a link, e.g. after a form submits:const navigate = useNavigate(productRoute); const onSubmit = async (form: FormData) => { const { id } = await createProduct(form); navigate({ productId: id }); };navigatealways pushes. For areplacenavigation, useuseSetAtom(routeAtom)directly and pass{ replace: true }as its second argument.useLink(routeAtom, values, { exact? })- whatLinkitself is built on:href,activeand anonClickhandler in one call, for link-like UI that isn't an<a>- a styled<div>card that navigates on click, for instance.
useHref and useLink both still subscribe to routeAtom, since reverse() can depend on
ancestor route state - so a component using either re-renders on navigation even when the href
it computes doesn't change.
Route atoms are only jotai atoms, so none of this is a closed set: useAtomValue(someRouteAtom)
and useSetAtom(someRouteAtom) are always available, and anything else in jotai's ecosystem works
on them unchanged. jarl-react re-exports useAtom, useAtomValue and useSetAtom for exactly
that reason, so reaching past the named hooks doesn't mean adding a direct jotai dependency:
import { useAtomValue } from "jarl-react";Link's fuller surface
Beyond route and to (optional - it defaults to {}, for routes that bind no params), Link
takes:
exact- only report itselfactive(see below) for an exact match, not an ancestor one.activeClassName- appended toclassNamewhile active.element- render as something other than<a>(ignored whenchildrenis a function).- Any standard anchor attribute, forwarded straight through.
Whether a link is "active" is also exposed as a data-active attribute (present only when active,
so a[data-active] { ... } styling doesn't need activeClassName plumbed through at all), and to
the function-as-child form:
<Link route={productRoute} to={{ productId: "123" }}>
{({ href, active, onClick }) => (
<CustomLink href={href} onClick={onClick} highlighted={active}>
Our Best Product Ever!
</CustomLink>
)}
</Link>onClick here already calls event.preventDefault() before navigating - pass it straight to the
underlying element as-is. When the markup isn't anchor-shaped at all, prefer useLink directly
over the render-prop form; it's the same three values without a component wrapped around them.