[PR #489] [MERGED] fix: make useParams() reactive on client-side navigation #612

Closed
opened 2026-05-06 13:09:04 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/489
Author: @NathanDrake2406
Created: 3/12/2026
Status: Merged
Merged: 3/12/2026
Merged by: @james-elicx

Base: mainHead: fix/use-params-reactivity


📝 Commits (3)

  • 88e58f6 fix: make useParams() reactive on client-side navigation
  • cfcc34a chore: fix formatting in test fixture
  • 8d55ec5 fix: stabilize useParams server snapshot and deduplicate subscribe

📊 Changes

3 files changed (+107 additions, -15 deletions)

View changed files

📝 packages/vinext/src/shims/navigation.ts (+27 -15)
📝 tests/e2e/app-router/nextjs-compat/hooks.spec.ts (+57 -0)
tests/fixtures/app-basic/app/nextjs-compat/hooks-params-nav/[id]/page.tsx (+23 -0)

📄 Description

Summary

  • useParams() was reading a module-level variable directly instead of subscribing via useSyncExternalStore, so navigating between dynamic routes (e.g. /posts/1/posts/2) wouldn't re-render components using useParams()
  • useParams() now uses useSyncExternalStore with the shared listener system, matching usePathname() and useSearchParams()
  • setClientParams() now calls notifyListeners() when params actually change, so the external store re-checks snapshots

Test plan

  • E2E: useParams updates reactively on client-side Link navigation (/1/2)
  • E2E: useParams updates across multiple consecutive navigations (/1/2/3/1)
  • E2E: useParams updates on browser back/forward history navigation
  • Unit: existing 659 shim tests pass (verified locally)
  • Typecheck and lint clean (verified locally)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/489 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 3/12/2026 **Status:** ✅ Merged **Merged:** 3/12/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/use-params-reactivity` --- ### 📝 Commits (3) - [`88e58f6`](https://github.com/cloudflare/vinext/commit/88e58f6c2c81d11e595a32b9c6396ec77956c5f0) fix: make useParams() reactive on client-side navigation - [`cfcc34a`](https://github.com/cloudflare/vinext/commit/cfcc34af14a3442b8779880edf52f459201c6e18) chore: fix formatting in test fixture - [`8d55ec5`](https://github.com/cloudflare/vinext/commit/8d55ec58efbe54d1ba8445b1ba548bf12a85e9b0) fix: stabilize useParams server snapshot and deduplicate subscribe ### 📊 Changes **3 files changed** (+107 additions, -15 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/shims/navigation.ts` (+27 -15) 📝 `tests/e2e/app-router/nextjs-compat/hooks.spec.ts` (+57 -0) ➕ `tests/fixtures/app-basic/app/nextjs-compat/hooks-params-nav/[id]/page.tsx` (+23 -0) </details> ### 📄 Description ## Summary - `useParams()` was reading a module-level variable directly instead of subscribing via `useSyncExternalStore`, so navigating between dynamic routes (e.g. `/posts/1` → `/posts/2`) wouldn't re-render components using `useParams()` - `useParams()` now uses `useSyncExternalStore` with the shared listener system, matching `usePathname()` and `useSearchParams()` - `setClientParams()` now calls `notifyListeners()` when params actually change, so the external store re-checks snapshots ## Test plan - [x] E2E: `useParams` updates reactively on client-side Link navigation (`/1` → `/2`) - [x] E2E: `useParams` updates across multiple consecutive navigations (`/1` → `/2` → `/3` → `/1`) - [x] E2E: `useParams` updates on browser back/forward history navigation - [x] Unit: existing 659 shim tests pass (verified locally) - [x] Typecheck and lint clean (verified locally) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:09:04 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#612
No description provided.