Skip to content

Instantly share code, notes, and snippets.

@mvantellingen
Created May 29, 2025 09:24
Show Gist options
  • Save mvantellingen/c058944bf8da9e04ae05a6ee19b1db1c to your computer and use it in GitHub Desktop.
Save mvantellingen/c058944bf8da9e04ae05a6ee19b1db1c to your computer and use it in GitHub Desktop.
/**
* This decorator (rscDecorator) is used to prevent infinite re-renders of
* rsc pages.
*
* See https://github.com/storybookjs/storybook/issues/30317#issuecomment-2615462131
*
* Rewritten to be compatible with Storybook 9
*/
let PrevStory: PartialStoryFn<ReactRenderer, object> | null = null;
let StoryPromise: ReactNode = null;
let promised = false;
const StoryPromiseWrapper = ({
Story,
}: { Story: Parameters<Decorator<object>>[0] }): ReactNode => {
if (PrevStory !== Story) {
promised = false;
PrevStory = Story;
}
/* eslint-disable */
const storyObj: JSX.Element = Story();
return {
...storyObj,
type: (...args) => {
const t = storyObj.type(...args);
return {
...t,
type: (...args) => {
if (!promised) {
StoryPromise = t
.type(...args)
.catch((err: unknown) => {
throw err;
})
.finally(() => {
promised = true;
});
}
return StoryPromise;
},
};
},
};
/* eslint-enable */
};
export const rscDecorator: Decorator<object> = (Story) => {
return (
<Suspense>
<StoryPromiseWrapper Story={Story} />
</Suspense>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment