How to use redwood's router useParams when writing storybooks?

The code for TestPage:

import { useParams } from '@redwoodjs/router'
const TestPage = () => {
  const { link, space } = useParams()
  return (
    <div>
      <p>This is link params {link}</p> <p>This is space {space}</p>
    </div>
  )
}
export default TestPage

How to write story for this page with different values of routing params ?

Hello @hassan-raza I just stumbled into this problem myself and was able use the useParams and useLocation with in Storybook.

The key was to use ParamsContext and LocationContext.

This is what my component looks like:

// TimeFilter.tsx - deeply-nested component 

import { useParams } from '@redwoodjs/router'
import { useLocation } from '@redwoodjs/router'
...
const TimeFilter = () => {
  const { pathname } = useLocation()
  const { period } = useParams()
...
}

export default TimeFilter

this is what the story looks like:

// TimeFilter.stories.ts

import type { ComponentMeta } from '@storybook/react'

import { ParamsContext } from '@redwoodjs/router'
import { LocationContext } from '@redwoodjs/router/dist/location'

import TimeFilter, { ALLOWED_PERIODS } from './TimeFilter'

export const generated = () => {
  return <TimeFilter />
}

export const withPeriod = (args) => {
  const period = args.period || ALLOWED_PERIODS[0]

  return (
    <LocationContext.Provider
      value={{ pathname: `entidades/nacional/${period}` }}
    >
      <ParamsContext.Provider
        value={{
          params: {
            period,
          },
        }}
      >
        <TimeFilter />
      </ParamsContext.Provider>
    </LocationContext.Provider>
  )
}

export default {
  title: 'Components/TimeFilter',
  component: TimeFilter,
  argTypes: {
    period: {
      options: ALLOWED_PERIODS,
      control: { type: 'select' },
    },
  },
} as ComponentMeta<typeof TimeFilter>

Since the state of this component is determined by the location and the params, I used the argTypes configuration so i can control it from storybook itself:

Hope this helps.

Do you, or anyone else know a better way to do it?

1 Like