Open
Description
Discussed in #12358
Originally posted by ryanflorence November 23, 2024
Right now you access active, pending, and transitioning states from a bunch of different hooks. This proposal hopes to consolidate them all into a simpler API.
Today
Accessing Current States
let location = useLocation()
let params = useParams()
let [searchParams] = useSearchParams()
let matches = useMatches()
let type = useNavigationType()
<NavLink to={path}>{({ isActive }) => isActive}</NavLink>
Accessing Pending States
let navigation = useNavigation()
navigation.location
// have to construct search params
let searchParams = new URLSearchParams(
navigation.location.search,
)
// no access
let params = undefined
let type = undefined
// access to form stuff (rarely used, fetchers usually better)
navigation.formAction // etc.
<NavLink to={path}>{({ isPending }) => isPending}</NavLink>
Accessing View Transition States
let state = useViewTransitionState(to)
<NavLink to={path}>
{({ isTransitioning }) => isTransitioning}
</NavLink>
Proposal: Consolidate into one hook
All of those hooks are either accessing active/pending states or matching against a path and providing active/pending states. We can do this with one hook.
type RouterStateVariant = {
location: Location
searchParams: URLSearchParams
params: Params
matches: Matches
}
type RouterState = {
active: RouterStateVariant
pending: null | RouterStateVariant
transitioning: boolean
}
let { active, pending, transitioning } = useRouterState()
// user clicks a link, both active and pending could have values
active.location
pending.location
By providing a path to the hook, we can match against it to determine the states, and even provide better types
type RouterStateVariant<Path> = {
location: Location<Path>
searchParams: URLSearchParams<Path>
params: Params<Path>
matches: Matches<Path>
type: NavigationType // Pop, Push, Replace
}
type RouterState<Path> = {
active: null | RouterStateVariant<Path>
pending: null | RouterStateVariant<Path>
transitioning: boolean
}
let { active, pending, transitioning } =
useRouterState('/projects/:id')
// the url is /projects/123
active.params.id
active.location // etc.
pending === null
// the url is /projects, user clicked /projects/123
active === null
pending.params.id
pending.location
Deprecations
This one hook can deprecate all eight of these:
useLocation
useSearchParams
useParams
useTransitionState
useNavigation
useMatches
useMatch(pattern)
useNavigationType
Refactor
Probably some potential refactoring to simplify the code and have the deprecated hooks (and NavLink) use the new hook underneath.
Metadata
Metadata
Assignees
Type
Projects
Status
Planned