I have a react component that grabs an id
from the route and uses that to load some data and populate the redux state.
I am using useParams
from 'react-router' to do this.
import { useParams } from 'react-router'
import { usePreload } from './hooks'
import Display from './Display'
const Overview = () => {
const { id } = useParams()
const { data } = usePreload(id) // uses useEffect to preload the data with the given id
return <Display data={data} />
}
export default Overview
I've got a story
import Overview from './Overview'
import preloadData from './decorators/preloadData'
export default {
title: 'Redux/scenes/Overview',
decorators: [preloadData()],
component: Overview,
argTypes: {}
}
const Template = args => <Overview {...args} />
export const Default = Template.bind({})
The preloadData
decorator is simply
import { usePreload } from '../hooks'
import { data } from './fixtures'
const Loaded = ({ children }) => {
useSubmissionsPreload(data.id) // loads the site data into the state
return <>{children}</>
}
const preloadData = () => Story => (
<Loaded>
<Story />
</Loaded>
)
export default preloadData
The code all works fine when actually running in the site but when running within a story there is no :id
in the path for useParams
to pick up.
For now I am just going to skip this story and just test the Display
component, but the completist in me demands to know how to get this to work.
To add the router to all the stories of a component, simply add it to the decorators array. Note that the parameters. reactRouter property is optional, by default the router will render the component at / .
You can use the connected-react-router library (formerly known as react-router-redux ). Their Github Repo details the steps for the integration. Once the setup is complete, you can now access the router state directly within Redux as well as dispatch actions to modify the router state within Redux actions.
With React Router, you have two options for creating nested routes. The first is using the /* with nested <Routes> pattern and the second is using the <Outlet /> pattern.
I also had the problem and the comment from De2ev pointed me in the right direction. It did however not work directly and I had to make slight changes. In the end it worked with the following code:
import React from "react";
import { Meta } from "@storybook/react";
import MyComponent from "./MyComponent";
import { MemoryRouter, Route} from "react-router-dom";
export default {
title: "My Title",
component: MyComponent,
decorators: [(Story) => (
<MemoryRouter initialEntries={["/path/58270ae9-c0ce-42e9-b0f6-f1e6fd924cf7"]}>
<Route path="/path/:myId">
<Story />
</Route>
</MemoryRouter>)],
} as Meta;
export const Default = () => <MyComponent />;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With