diff --git a/docs/api-reference/next/router.md b/docs/api-reference/next/router.md index 9c0e78dfd784e..f7e6b7144efbd 100644 --- a/docs/api-reference/next/router.md +++ b/docs/api-reference/next/router.md @@ -113,8 +113,6 @@ export default function Page() { } ``` -> **Note:** When navigating to the same page in Next.js, the page's state **will not** be reset by default, as the top-level React component is the same. You can manually ensure the state is updated using `useEffect`. - Redirecting the user to `pages/login.js`, useful for pages behind [authentication](/docs/authentication): ```jsx @@ -138,6 +136,62 @@ export default function Page() { } ``` +#### Resetting state after navigation + +When navigating to the same page in Next.js, the page's state **will not** be reset by default: + +```jsx +// pages/[pageTitle].jsx + +import Link from "next/link" +import { useState } from "react" + +export const getServerSideProps = async ({ params }) => ({ + props: { + pageTitle: params["pageTitle"] + } +}) + +export default function Page({ pageTitle }) { + const [title] = useState(pageTitle) + return ( +
+

{title}

+ + one + {" "} + + two + +
+ ) +} +``` + +Above, navigating between `/foo` and `/bar` **will not** change the page title. The `useState` is initialized for the first `Page` component, and not re-initialized when navigating to a different `Page` instance. This is because the top-level React component, `Page`, is the same. + +If you do not want this behavior, you have a couple of options: + +1. Manually ensure each state is updated using `useEffect`. Above, that could look like: + + ```jsx + useEffect(() => { + setTitle(pageTitle) + }, [pageTitle]) + ``` + +2. Use a React `key` to [tell React to remount the component](https://kentcdodds.com/blog/understanding-reacts-key-prop#:~:text=This%20allows%20you%20to%20return%20the%20exact%20same%20element%20type%2C%20but%20force%20React%20to%20unmount%20the%20previous%20instance%2C%20and%20mount%20a%20new%20one.). To do this for all pages, you can use a custom app: + + ```jsx + // pages/_app.jsx + import { useRouter } from "next/router" + + export default function MyApp({ Component, pageProps }) { + const router = useRouter() + return + } + ``` + #### With URL object You can use a URL object in the same way you can use it for [`next/link`](/docs/api-reference/next/link.md#with-url-object). Works for both the `url` and `as` parameters: