0

I am understanding the error message, but not sure how I should handle it in this case. I believe that using the decorator below is causing the issue, but the decorator is needed to use the component with Storybook.

Here is the error message:

You cannot render a <Router> inside another <Router>. You should never have more than one in your app.

Believe this is due to the decorator and I can only assume the BrowserRouter found way upstream in my app, but from what I understand, Storybook isn't loading my index file. So I'm unsure how to proceed.

Here is the component, simplified:

export const Component = () => {
  ...

  return (
    <Routes>
          <Route path="/screening" element={<Screening {...propBag} />} />
        </Routes>
  );
};

Then, the Story:

import { Story, Meta } from '@storybook/react';
import { MemoryRouter } from 'react-router-dom';

import { Component } from '..';

export default {
  title: 'Province',
  component: Component,
  decorators: [
    (Story) => (
      <MemoryRouter>
        <Story />
      </MemoryRouter>
    )
  ],
} as Meta;

const Template: Story = (args) => <IntakeQuestionnaire {...args} />;

export const Province = Template.bind({});
Province.parameters = {};
Province.args = {};

Finally, the preview.js file:

import 'tailwindcss/tailwind.css';
import { MockedProvider } from '@apollo/client/testing';

import { i18n } from './i18next';

export const parameters = {
  i18n,
  locale: 'en',
  locales: {
    en: 'English',
    fr: 'Français',
  },
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
  apolloClient: { MockedProvider },
};

export const decorators = [
  (Story) => (
      <MemoryRouter>
        <Story />
      </MemoryRouter>
    )
];
ChumiestBucket
  • 868
  • 4
  • 22
  • 51
  • I guess I'll ask the obvious question then - why are you adding two routers to your app? – Randy Casburn Nov 15 '21 at 17:07
  • Are you using v6? – Randy Casburn Nov 15 '21 at 17:16
  • Does this answer your question? [You cannot render a inside another . You should never have more than one in your app](https://stackoverflow.com/questions/69828516/you-cannot-render-a-router-inside-another-router-you-should-never-have-more) – Randy Casburn Nov 15 '21 at 17:17
  • @RandyCasburn the use of Storybook is a key component in this case. Storybook doesn't render the upstream index file containing the app's main Router, so there is only one Router being rendered in the app: MemoryRouter. i think the error is misleading for this reason – ChumiestBucket Nov 15 '21 at 17:19

1 Answers1

1

Not sure why, but removing the decorators array from preview.js file and putting it only in the component Story file fixed this issue. Less than ideal but at least I am unblocked now

export default {
  title: 'Province',
  component: Component,
  decorators: [
    (Story) => (
      <MemoryRouter>
        <Story />
      </MemoryRouter>
    )
  ],
} as Meta;

EDIT: see below comment - i was being silly with decorators

ChumiestBucket
  • 868
  • 4
  • 22
  • 51
  • 1
    You can think of decorators in `preview.js` as "global" decorators. On the other side, decorators in story itself is "local" decorator. This way you managed to have two `MemoryRouter` decorators. – Allwe Jun 08 '22 at 19:09
  • @Allwe That makes sense. Any idea how to make a global decorator (or addon decorator) behave the same? – Eddie Monge Jr Oct 12 '22 at 18:39
  • @EddieMongeJr It depends. If all your stories needs to be child of `MemoryRouter`, then it makes sense to put in `preview.js`, but you can't decorate individual stories with it again. If only bunch of your stories needs router, then I would suggest to decorate just those. – Allwe Apr 13 '23 at 10:38