Storybook添加Header组件时react-redux Provider缺失错误的原因与解决方法
问题原因与修复方案
问题原因
- Storybook是独立的组件预览环境,和主应用的入口配置完全隔离,你在主入口
index.tsx里配置的<Provider>不会作用到Storybook的组件渲染流程。 - Header组件内部使用了
useAppDispatch、useAppSelector等Redux Hooks,这类钩子必须在Redux的<Provider>上下文包裹下才能正常运行,Storybook默认没有提供这个上下文,所以抛出找不到context的错误。 - 你提到的ProviderDecorator没生效,大概率是因为装饰器没有传入正确的store实例,或者装饰器的加载顺序不符合上下文嵌套要求。
修复步骤
1. 创建Redux装饰器
在你的Storybook装饰器目录下新建ReduxDecorator.tsx文件,导入项目的store和Redux的Provider,用来包裹Story组件:
import { Provider } from 'react-redux'; import { store } from '../../app/store'; // 替换成你项目中store的实际路径 export const ReduxDecorator = (Story: any) => ( <Provider store={store}> <Story /> </Provider> );
2. 补充其他依赖上下文的装饰器
Header组件还用到了useLocation(react-router)和useTranslation(react-i18next),同样需要对应的装饰器来提供上下文:
Router装饰器(处理useLocation)
import { BrowserRouter } from 'react-router-dom'; export const RouterDecorator = (Story: any) => ( <BrowserRouter> <Story /> </BrowserRouter> );
I18n装饰器(处理useTranslation)
import { I18nextProvider } from 'react-i18next'; import i18n from '../../i18n'; // 替换成你项目中i18n实例的实际路径 export const I18nDecorator = (Story: any) => ( <I18nextProvider i18n={i18n}> <Story /> </I18nextProvider> );
3. 在Header的Story中添加装饰器
修改Header的Story文件,按照主入口的上下文嵌套顺序添加装饰器(Redux在外层,依次是Router、I18n、样式、主题):
import { Meta, StoryObj } from '@storybook/react'; import Header from './Header'; import { StyleDecorator } from '../decorators/StyleDecorator'; import { ThemeDecorator } from '../decorators/ThemeDecorator'; import { ReduxDecorator } from '../decorators/ReduxDecorator'; import { RouterDecorator } from '../decorators/RouterDecorator'; import { I18nDecorator } from '../decorators/I18nDecorator'; const meta = { title: 'page/Header', component: Header, decorators: [ ReduxDecorator, RouterDecorator, I18nDecorator, StyleDecorator, ThemeDecorator('dark_theme'), ], } satisfies Meta<typeof Header>; export default meta; type Story = StoryObj<typeof meta>; export const HeaderLight: Story = { args: {}, decorators: [ThemeDecorator('light_theme')], // 单独覆盖主题配置 }; export const HeaderDark: Story = { args: {}, };
4. (可选)全局配置装饰器
如果希望所有Story都自动应用这些上下文装饰器,可以在.storybook/preview.tsx中全局配置:
import type { Preview } from '@storybook/react'; import { ReduxDecorator } from '../src/stories/decorators/ReduxDecorator'; import { RouterDecorator } from '../src/stories/decorators/RouterDecorator'; import { I18nDecorator } from '../src/stories/decorators/I18nDecorator'; const preview: Preview = { decorators: [ReduxDecorator, RouterDecorator, I18nDecorator], // 其他Storybook配置... }; export default preview;
内容的提问来源于stack exchange,提问作者Максим Дмитриевич
相关产品推荐
相关产品推荐

