如何在Storybook全局装饰器中正确调用React自定义Hooks
问题根源
你当前的实现存在两个核心问题:
useCustomHooks的调用位置在ThemeProvider外层,不在Context作用域范围内,无法访问Provider注入的上下文,必然运行报错- React Hook仅允许在函数组件、自定义Hook的顶层调用,你当前写法直接在JSX相邻位置裸写Hook,既不符合Hook调用规则,也存在JSX语法错误
解决方案
核心思路:将自定义Hook的调用逻辑移动到Context Provider的子组件内部,保证Hook执行时已经处于Provider包裹的作用域下即可,全局配置一次即可对所有故事生效。
正确实现代码如下:
import React from 'react'; import { useCustomHooks } from './custom'; import { ThemeProvider } from 'styled-components'; // 定义Provider内部的辅助组件,专门承担Hook调用逻辑 const GlobalHookRunner = ({ children }) => { // 此处已处于ThemeProvider作用域内,自定义Hook可以正常访问所有上下文 useCustomHooks(); // 如果需要把Hook的返回值透传给所有故事,可以通过props注入 // const hookRes = useCustomHooks(); // return React.cloneElement(children, { globalHookData: hookRes }); return <>{children}</>; }; export const decorators = [ (Story) => ( <ThemeProvider theme="default"> <GlobalHookRunner> <Story /> </GlobalHookRunner> </ThemeProvider> ), ];
补充说明
- 如果需要自定义Hook仅在全局初始化一次、避免切换故事时重复执行,可以给
GlobalHookRunner包裹React.memo做缓存,或者将对应状态提升到Provider层级管理 - 该方案兼容所有需要依赖Context的自定义Hook,不需要在单个故事文件里重复配置Provider和调用逻辑
内容的提问来源于stack exchange,提问作者Pytan
相关产品推荐
相关产品推荐

