Tackling the useNavigate Error in Storybook

I recently ran into an error in my Storybook environment that read: useNavigate() may be used only in the context of a component. It took me a moment to understand why this was happening, and I want to share how I solved it.

Thank me by sharing on Twitter 🙏

Error: useNavigate() may be used only in the context of a component.

Why This Error Occurs

I discovered that Storybook doesn’t automatically provide a React Router context. When I used useNavigate(), React expected my component to be nested inside a <Router> component, but Storybook had no router set up by default. Consequently, it complained that I was calling useNavigate() outside a router.

How I Wrapped My Component in a Router

To fix the issue, I wrapped the story in a <MemoryRouter> decorator. This way, my component could use all the router hooks, including useNavigate(). Here’s a simplified example:

TypeScript
import type { Meta, StoryObj } from "@storybook/react";
import { fn } from "@storybook/test";
import { MemoryRouter } from "react-router-dom";

import MyComponent from './MyComponent';

const meta = {
	title: "Examples/MyComponent",
	component: MyComponent,
	tags: ["autodocs"],
	parameters: {
		layout: "fullscreen",
	},
	args: {
		onLogin: fn(),
		onLogout: fn(),
		onCreateAccount: fn(),
	},
	decorators: [
		(Story) => (
			<MemoryRouter>
				<Story />
			</MemoryRouter>
		),
	],
} satisfies Meta<typeof MyComponent>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Basic: Story = {};

Once I added this decorator, Storybook provided the same router context I would normally have in a standard React application. I was then free to call useNavigate() without errors.

Verifying My Fix

After I refreshed Storybook, the error disappeared. The navigation logic within my component worked as expected, and I confirmed that my stories still rendered correctly.

Final Thoughts

By wrapping my stories with a <MemoryRouter>, I ensured that any calls to useNavigate() had the proper context. This small change saved me a lot of time and kept my Storybook environment aligned with my production setup. I hope my experience helps anyone else who faces the same challenge.

Share this:

Leave a Reply