pbeshai / use-query-params

React Hook for managing state in URL query parameters with easy serialization.

Home Page:https://pbeshai.github.io/use-query-params

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

React Router 6 Adapter breaks when using `createBrowserRouter`

NerdCowboy opened this issue · comments

When using with ReactRouter6Adapter, if you use the React Router 6's object syntax with createBrowserRouter it throws an error:
Uncaught TypeError: Cannot destructure property 'navigator' of '(0 , import_react.useContext)(...)' as it is null.

This still holds, what was the reason you closed it?

Failing to remember exactly, but this was not an issue with use-query-params.

I believe the issue may have been that I didn't have the Rect RouterProvider mounted/wrapped around the QueryParamProvider

With createBrowserRouter api we don't have a way of defining a top level QueryParamProvider as in

 <BrowserRouter>
    <QueryParamProvider 
      adapter={ReactRouter6Adapter}
    >
      <Routes>
        ......

We create a router which defines all routes as objects using createBrowserRouter and directly pass it to RouterProvider:

<RouterProvider router={router} />

I tried defining a top level layout route in router so all the routes get wrapped with the param provider:

      element: <QueryParamProvider adapter={ReactRouter6Adapter} />,
      children: [
        {
          path: '/',
          ....

but it errors with

 Property 'children' is missing in type '{ adapter: QueryParamAdapterComponent; }' but required in type '{ children: ReactNode; }'.

as adapter is implemented in a way that it needs to have children using JSX syntax.

You should be able to do something like the following, right?

export const router = createBrowserRouter([
  {
    path: '/',
    element: (
      <QueryParamProvider
        adapter={ReactRouter6Adapter}
        options={useQueryParamsOptions}
      >
        <Outlet />
      </QueryParamProvider>
    ),
    children: [...]
  }
]

Ahh, I forgot adding <Outlet /> to my top level layout route. I actually don't have to bind the provider to a specific path:

const router = createBrowserRouter(
  [
    {
      element: (
        <QueryParamProvider adapter={ReactRouter6Adapter}>
          <Outlet />
        </QueryParamProvider>
      ),
      children: [
        {
        ...

works and should be equivalent of

<BrowserRouter>
    <QueryParamProvider 
      adapter={ReactRouter6Adapter}
    >
      <Routes>
        ...

Thanks for the reminder.