next-router-mock: Cannot use default (singleton) router: "You should only use "next/router" on the client side of your app"
Hello! First of all thanks for awesome package, @scottrippey!
I try to mock next-router with storybook. Is it real to mock default Router as we do it for useRouter?
For instance useRouter works fine:
useRouter example
import { useCallback } from 'react'
import { useRouter } from 'next/router'
const UseRouterPage = () => {
const router = useRouter()
const handleClick = useCallback(() => router.push({
pathname: router?.pathname,
query: {
...router?.query,
test: '1'
},
}, undefined,
{
scroll: false,
shallow: true
}), [])
return (
<main>
<button onClick={handleClick}>button</button>
</main>
)
}
export default UseRouterPage
But with default exported Router, the next error appears:
I try use default exported Router because in this case there is no component re-render.
useRouter example
import { useCallback } from 'react'
import Router from 'next/router'
const RouterPage = () => {
const handleClick = useCallback(() => Router.push({
pathname: Router?.pathname,
query: {
...Router?.query,
test: '1'
},
}, undefined,
{
scroll: false,
shallow: true
}), [])
return (
<main>
<button onClick={handleClick}>button</button>
</main>
)
}
export default RouterPage
Repo to reproduce: https://github.com/sedlukha/next-router-mock-example
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 21 (11 by maintainers)
@amolagre I had the same
ModuleNotFoundError
error as you, but it seems to work by importing thenext-12
version specifically:Hi @scottrippey , Any update to make
next/link
(12.2) working with storybook. I’m getting this error while runningnpm run storybook
ModuleNotFoundError: Module not found: Error: Can't resolve 'next/dist/next-server/lib/router-context' in 'my-project\node_modules\next-router-mock\dist\MemoryRouterProvider'
@scottrippey I use a singleton router for both: read pathname/query and push/replace.
From a Storybook point-of-view, I don’t use
<MemoryRouterProvider onPush={...} onReplace={...}>
events. I mock the given URL and change it via push/replace inside the story.My use-case is a complex search page with search results, filters, and a load more button. I write stories with the play function to check how the router changed after filters/pagination manipulations.
And everything works great with
useRouter
. I can write any test/story and everything will be fine.But I prefer to use a singleton router to reduce component renders. For instance, let’s take a look at the load more button. When you press it, you want to add a query (e.g. ?page=2) to the URL without the button rerender.
But if you use useRouter, there would be rerendering on every query change.
That’s why I prefer to use a singleton router. In this case, I read query and push only in a callback.