diff --git a/code/lib/preview-api/src/modules/addons/hooks.ts b/code/lib/preview-api/src/modules/addons/hooks.ts index e695938a444d..ce1643315824 100644 --- a/code/lib/preview-api/src/modules/addons/hooks.ts +++ b/code/lib/preview-api/src/modules/addons/hooks.ts @@ -70,7 +70,7 @@ export class HooksContext init() { this.hookListsMap = new WeakMap(); this.mountedDecorators = new Set(); - this.prevMountedDecorators = this.mountedDecorators; + this.prevMountedDecorators = new Set(); this.currentHooks = []; this.nextHookIndex = 0; this.currentPhase = 'NONE'; @@ -191,7 +191,7 @@ export const applyHooks = ); return (context) => { const { hooks } = context as { hooks: HooksContext }; - hooks.prevMountedDecorators = hooks.mountedDecorators; + hooks.prevMountedDecorators ??= new Set(); hooks.mountedDecorators = new Set([storyFn, ...decorators]); hooks.currentContext = context; hooks.hasUpdates = false; diff --git a/code/lib/preview-api/src/modules/store/hooks.test.ts b/code/lib/preview-api/src/modules/store/hooks.test.ts index bbd72f95b0a5..655a41249b4f 100644 --- a/code/lib/preview-api/src/modules/store/hooks.test.ts +++ b/code/lib/preview-api/src/modules/store/hooks.test.ts @@ -147,6 +147,25 @@ describe('Preview hooks', () => { run(story, [decorator]); expect(effect).toHaveBeenCalledTimes(1); }); + it('handles decorator conditionally rendering the story', () => { + const effect = jest.fn(); + const story = () => { + useEffect(effect, []); + }; + const decorator = (storyFn: any) => { + const [counter, setCounter] = useState(0); + useEffect(() => { + setCounter((prevCounter) => prevCounter + 1); + }, [counter]); + if (counter % 2 === 1) storyFn(); + return 'placeholder while waiting'; + }; + run(story, [decorator]); + run(story, [decorator]); + run(story, [decorator]); + run(story, [decorator]); + expect(effect).toHaveBeenCalledTimes(2); + }); it('retriggers the effect if some of the deps are changed', () => { const effect = jest.fn(); let counter = 0;