Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
After speaking with @timneutkens, this PR provides a smoother experience to users trying to migrate over to app without affecting users in pages. This PR adds a new export available from `next/compat/router` that exposes a `useRouter()` hook that can be used in both `app/` and `pages/`. It differs from `next/router` in that it does not throw an error when the pages router is not mounted, and instead has a return type of `NextRouter | null`. This allows developers to convert components to support running in both `app/` and `pages/` as they are transitioning over to `app/`. A component that before looked like this: ```tsx import { useRouter } from 'next/router'; const MyComponent = () => { const { isReady, query } = useRouter(); // ... }; ``` Will error when converted over to `next/compat/router`, as `null` cannot be destructured. Instead, developers will be able to take advantage of new hooks: ```tsx import { useEffect } from 'react'; import { useRouter } from 'next/compat/router'; import { useSearchParams } from 'next/navigation'; const MyComponent = () => { const router = useRouter() // may be null or a NextRouter instance const searchParams = useSearchParams() useEffect(() => { if (router && !router.isReady) { return } // In `app/`, searchParams will be ready immediately with the values, in // `pages/` it will be available after the router is ready. const search = searchParams.get('search') // ... }, [router, searchParams]) // ... } ``` This component will now work in both `pages/` and `app/`. When the component is no longer used in `pages/`, you can remove the references to the compat router: ```tsx import { useSearchParams } from 'next/navigation'; const MyComponent = () => { const searchParams = useSearchParams() // As this component is only used in `app/`, the compat router can be removed. const search = searchParams.get('search') // ... } ``` Note that as of Next.js 13, calling `useRouter` from `next/router` will throw an error when not mounted. This now includes an error page that can be used to assist developers. We hope to introduce a codemod that can convert instances of your `useRouter` from `next/router` to `next/compat/router` in the future. Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
- Loading branch information
Showing
9 changed files
with
44 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# NextRouter was not mounted | ||
|
||
#### Why This Error Occurred | ||
|
||
A component used `useRouter` outside a Next.js application, or was rendered outside a Next.js application. This can happen when doing unit testing on components that use the `useRouter` hook as they are not configured with Next.js' contexts. | ||
|
||
#### Possible Ways to Fix It | ||
|
||
If used in a test, mock out the router by mocking the `next/router`'s `useRouter()` hook. | ||
|
||
### Useful Links | ||
|
||
- [next-router-mock](https://www.npmjs.com/package/next-router-mock) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useContext } from 'react' | ||
import { RouterContext } from '../../shared/lib/router-context' | ||
import { NextRouter } from '../router' | ||
|
||
/** | ||
* useRouter from `next/compat/router` is designed to assist developers | ||
* migrating from `pages/` to `app/`. Unlike `next/router`, this hook does not | ||
* throw when the `NextRouter` is not mounted, and instead returns `null`. The | ||
* more concrete return type here lets developers use this hook within | ||
* components that could be shared between both `app/` and `pages/` and handle | ||
* to the case where the router is not mounted. | ||
* | ||
* @returns The `NextRouter` instance if it's available, otherwise `null`. | ||
*/ | ||
export function useRouter(): NextRouter | null { | ||
return useContext(RouterContext) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from '../dist/client/compat/router' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('../dist/client/compat/router') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters