模拟 providers
组件可以从 context providers 接收数据或配置。例如,一个 styled component 可能会从 ThemeProvider 访问其主题,或者 Redux 使用 React context 来提供组件访问应用数据。要模拟 provider,你可以将你的组件包裹在一个 decorator 中,该 decorator 包含必要的 context。
.storybook/preview.tsx
import React from 'react';
import { Preview } from '@storybook/react';
import { ThemeProvider } from 'styled-components';
const preview: Preview = {
decorators: [
(Story) => (
<ThemeProvider theme="default">
{/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it */}
<Story />
</ThemeProvider>
),
],
};
export default preview;
注意上面的文件扩展名(.tsx
或 .jsx
)。你可能需要调整你的预览文件的扩展名以允许使用 JSX,具体取决于你的项目设置。
有关另一个示例,请参考 Storybook 入门教程的 Screens 章节,我们在其中使用模拟数据模拟了 Redux provider。
配置模拟 provider
在模拟 provider 时,可能需要配置 provider 以便为各个 story 提供不同的值。例如,你可能想要使用不同的主题或用户角色来测试组件。
一种方法是为每个 story 单独定义 decorator。但是,如果你设想一种场景,你希望为浅色和深色主题中的每个组件创建 story,这种方法很快就会变得很麻烦。
为了获得更好、重复性更低的方法,你可以使用 decorator 函数的第二个 “context” 参数 来访问 story 的 parameters
并调整提供的值。这样,你可以定义一次 provider,并为每个 story 调整其值。
例如,我们可以调整上面的 decorator 以从 parameters.theme
读取,以确定要提供的主题
.storybook/preview.tsx
import React from 'react';
import type { Preview } from '@storybook/react';
import { ThemeProvider } from 'styled-components';
// themes = { light, dark }
import * as themes from '../src/themes';
const preview: Preview = {
decorators: [
// 👇 Defining the decorator in the preview file applies it to all stories
(Story, { parameters }) => {
// 👇 Make it configurable by reading the theme value from parameters
const { theme = 'light' } = parameters;
return (
<ThemeProvider theme={themes[theme]}>
<Story />
</ThemeProvider>
);
},
],
};
export default preview;
现在,你可以在你的 stories 中定义一个 theme
参数,以调整 decorator 提供的主题
Button.stories.ts
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
};
export default meta;
type Story = StoryObj<typeof Button>;
// Wrapped in light theme
export const Default: Story = {};
// Wrapped in dark theme
export const Dark: Story = {
parameters: {
theme: 'dark',
},
};
这种强大的方法允许你以灵活且可维护的方式为组件提供任何值(主题、用户角色、模拟数据等)。