0

Storybook с react-router: Не используйте <Link> вне <Router>

9

Проблема с использованием <Link> вне <Router> в Storybook

Я хотел бы поделиться решением проблемы, с которой столкнулся, несмотря на мои навыки поиска в Google.

Мое приложение, использующее react-router, работало без каких-либо проблем, но при запуске Storybook возникла ошибка:

Error: Invariant failed: You should not use <Link> outside a <Router>
    at invariant (tiny-invariant.esm.js:11)
    at react-router-dom.js:181
    at updateContextConsumer (react-dom.development.js:19747)
    at beginWork$1 (react-dom.development.js:20079)
    ...

Это странно, так как само приложение работало (и, следовательно, ни один <Link> не использовался вне <Router>).
Как можно решить эту проблему, чтобы Storybook корректно работал с компонентами, использующими react-router?

3 ответ(ов)

0

Вот что сработало для меня. Добавьте MemoryRouter в свойство decorators.

import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import //ваш компонент// из //местоположение компонента//

export default {
  title: //Как вы хотите, чтобы ваш компонент отображался в Storybook, например: 'Компоненты/Кнопка'
  component: //Укажите имя компонента, который вы импортировали, например: 'Кнопка'
  decorators: [(Story) => (<MemoryRouter><Story/></MemoryRouter>)] // Оборачиваем историю в роутер
};

Этот код позволит вашему компоненту правильно работать с маршрутизацией в Storybook.

0

В дополнение к ответу Web-ski, добавьте StoryRouter в ваш файл .storybook/preview.js:

import StoryRouter from 'storybook-react-router';

addDecorator(StoryRouter());

Теперь он будет доступен глобально в каждой истории.

0

Если вы хотите сделать это для отдельного компонента, а не глобально, то в файле историй оберните компонент в MemoryRouter.

Например, у меня есть компонент заголовка, который содержит элемент Link, поэтому в файле header.stories.tsx я изменю следующее:

const Template: ComponentStory<typeof Header> = (args) => (
    <Header {...args} />
);

на

const Template: ComponentStory<typeof Header> = (args) => (
  <MemoryRouter>
    <Header {...args} />
  </MemoryRouter>
);

Таким образом, вы сможете корректно использовать компонент Link внутри вашего заголовка в среде Storybook.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь