带React-Router的Storybook-您不应在<Router>外使用<Link>

时间:2019-11-18 07:21:15

标签: javascript reactjs react-router storybook

发布问题的解决方案尽管我有Sensei Googling技能,但我还是很难找到

尽管我的带有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)
    at HTMLUnknownElement.callCallback (react-dom.development.js:358)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:410)
    at invokeGuardedCallback (react-dom.development.js:463)
    at beginWork$$1 (react-dom.development.js:25730)
    at performUnitOfWork (react-dom.development.js:24631)
    at workLoopSync (react-dom.development.js:24613)

奇怪,因为该应用正常运行(因此,没有在外部使用

)。

问题在于Storybook呈现了单个故事。在这种情况下,组件using实际上是在。外部渲染的。

解决方案是使用addDecorator包装单个故事;

//config.js
//...
addDecorator(story => <Router>{story()}</Router>);

5 个答案:

答案 0 :(得分:14)

对我来说,是这样的:

  1. 在您的preview.js文件夹中创建一个.storybook文件。
  2. 在您的preview.js文件中添加以下全局修饰符。
    import React from "react";
    import { addDecorator } from "@storybook/react";
    import { MemoryRouter } from "react-router';

    addDecorator(story => <MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>);

注释

  • 使用的故事书版本:"@storybook/react": "^5.3.13"
  • 基于此解决方案developer doc
  • 有关全局装饰器的更多信息here

答案 1 :(得分:1)

这对我有用。在decorators属性内添加Memory Router。

<table border="1">
  <tr>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
  <tr>
  <tr>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
  <tr>
  <tr>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
  <tr>
  <tr>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
    <td>Hello World</td>
  <tr>
</table>

答案 2 :(得分:1)

Storybook 6.1 版在新代码表示法中使用 storybook-router。以下是单个组件的示例:

import React from 'react';
import StoryRouter from 'storybook-react-router';
import //your component// from //component location//

export default {
  title: '//your component//',
  component: //your component//,
  decorators: [StoryRouter()],
};

export const Name = () => <//your component// />;

答案 3 :(得分:0)

Web-ski 的进一步回答。将 StoryRouter 添加到您的 .storybook/preview.js

import StoryRouter from 'storybook-react-router';

addDecorator(StoryRouter());

现在可在全球范围内的每个故事中使用。

答案 4 :(得分:-1)

问题在于Storybook呈现了单个故事。在这种情况下,使用<Link>的组件实际上是在<Router>外部渲染的。

解决方案是使用addDecorator用<Router>包装单个故事;

//config.js
//...
addDecorator(story => <Router>{story()}</Router>);