Storybook с react-router: Не используйте <Link> вне <Router>
Проблема с использованием <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 ответ(ов)
Вот что сработало для меня. Добавьте MemoryRouter
в свойство decorators
.
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import //ваш компонент// из //местоположение компонента//
export default {
title: //Как вы хотите, чтобы ваш компонент отображался в Storybook, например: 'Компоненты/Кнопка'
component: //Укажите имя компонента, который вы импортировали, например: 'Кнопка'
decorators: [(Story) => (<MemoryRouter><Story/></MemoryRouter>)] // Оборачиваем историю в роутер
};
Этот код позволит вашему компоненту правильно работать с маршрутизацией в Storybook.
В дополнение к ответу Web-ski, добавьте StoryRouter
в ваш файл .storybook/preview.js
:
import StoryRouter from 'storybook-react-router';
addDecorator(StoryRouter());
Теперь он будет доступен глобально в каждой истории.
Если вы хотите сделать это для отдельного компонента, а не глобально, то в файле историй оберните компонент в 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.
Как программно выполнять навигацию с помощью React Router?
React-router URLs не работают при обновлении страницы или ручном вводе адреса
Обнаружена ошибка: Невозможное нарушение: Неверный тип элемента: ожидался строковый тип (для встроенных компонентов) или класс/функция, но получен объект
"Не используйте Route или withRouter() вне Router при работе с react-router 4 и styled-components в React"
Использование IndexRoute в react-router v4 с React