React Router v6

在你的故事中使用 React Router v6

在 Github 上查看

Storybook Addon Remix React Router

Storybook npm Release npm

在你的故事中使用 Remix React Router。

✨注意✨
该包已更名为storybook-addon-remix-react-router
仓库也已重命名,因此您位于正确的页面。
为了支持 Storybook 8,迁移是强制性的。

最近的变更

✅ 使用storybook-addon-remix-react-router@3支持 Storybook 8。
✅ 您现在可以使用useStoryElement在多个位置注入故事。
routing参数现在接受一个字符串,该字符串将用作路由路径和位置路径名。

入门

安装包

npm i -D storybook-addon-remix-react-router

将其添加到你的 Storybook 配置中

// .storybook/main.ts

export default {
  addons: ['storybook-addon-remix-react-router'],
} satisfies StorybookConfig;

装饰组件的所有故事

要将路由器添加到组件的所有故事,只需将其添加到decorators数组中即可。

请注意,parameters.reactRouter是可选的,默认情况下路由器将在/渲染组件。

import { withRouter } from 'storybook-addon-remix-react-router';

export default {
  title: 'User Profile',
  render: () => <UserProfile />,
  decorators: [withRouter],
  parameters: {
    reactRouter: reactRouterParameters({
      location: {
        pathParams: { userId: '42' },
      },
      routing: { path: '/users/:userId' },
    }),
  },
};

装饰特定故事

要更改单个故事的配置,可以执行以下操作

import { withRouter } from 'storybook-addon-remix-react-router';

export default {
  title: 'User Profile',
  render: () => <UserProfile />,
  decorators: [withRouter],
};

export const FromHomePage = {
  parameters: {
    reactRouter: reactRouterParameters({
      location: {
        pathParams: { userId: '42' },
        searchParams: { tab: 'activityLog' },
        state: { fromPage: 'homePage' },
      },
      routing: {
        path: '/users/:userId',
        handle: 'Profile',
      },
    }),
  },
};

全局装饰所有故事

通过在你的preview.js文件中添加装饰器,将你项目的所有故事包装在路由器中。

// .storybook/preview.js

export default {
  decorators: [withRouter],
  parameters: {
    reactRouter: reactRouterParameters({ ... }),
  }
} satisfies Preview;

位置

要指定与浏览器位置相关的任何内容,请使用location属性。

type LocationParameters = {
  path?: string | ((inferredPath: string, pathParams: Record<string, string>) => string | undefined);
  pathParams?: PathParams;
  searchParams?: ConstructorParameters<typeof URLSearchParams>[0];
  hash?: string;
  state?: unknown;
};

推断路径

如果没有提供location.path,浏览器路径名将使用来自routing属性和pathParams的连接的path生成。

路径作为函数

你可以为path提供一个函数。
它将接收来自routing属性和pathParams的连接的path作为参数。
如果函数返回一个string,它将按原样使用。如果你需要,你可以调用来自react-routergeneratePath
如果函数返回undefined,它将回退到默认行为,就像你没有为location.path提供任何值一样。

路由

你可以将routing设置为createBrowserRouter接受的任何内容。
为了让你的生活更轻松,storybook-addon-remix-react-router附带了一些路由助手

export const MyStory = {
  parameters: {
    reactRouter: reactRouterParameters({
      routing: reactRouterOutlet(<MyOutlet />),
    }),
  },
};

路由助手

以下助手开箱即用

reactRouterOutlet(); // Render a single outlet
reactRouterOutlets(); // Render multiple outlets
reactRouterNestedOutlets(); // Render multiple outlets nested one into another
reactRouterNestedAncestors(); // Render the story as an outlet of nested outlets

你也可以创建自己的助手并使用导出的类型RoutingHelper来帮助你

import { RoutingHelper } from 'storybook-addon-remix-react-router';

const myCustomHelper: RoutingHelper = () => {
  // Routing creation logic
};

RouterRoute基本上是来自react-router的原生RouteObject;用{ useStoryElement?: boolean }增强。如果你想接受一个 JSX 并将其转换为RouterRoute,你可以使用导出的函数castRouterRoute

使用故事作为路由元素

只需在路由配置对象中设置{ useStoryElement: true }

专用面板

导航事件、加载程序和操作将被记录,以便你更好地了解组件的生命周期。

Addon Panel

兼容性

需要react-router的版本6.4+。该包旨在支持Storybook > 7React > 16

✅ Storybook 8.0
✅ Storybook 7.0

✅ React 18
✅ React 17
✅ React 16

如果你在任何版本中遇到问题,请提交一个 issue。

贡献

欢迎贡献。

在编写任何代码之前,请提交一个 issue 来展示你想在这个插件中看到的错误或用例。

许可证

该包在 Apache 2.0 许可证下发布。