Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: array or object with JSX elements in context causes Storybook to hang indefinitely #19575

Open
alicnik opened this issue Oct 21, 2022 · 20 comments · May be fixed by #27373
Open

[Bug]: array or object with JSX elements in context causes Storybook to hang indefinitely #19575

alicnik opened this issue Oct 21, 2022 · 20 comments · May be fixed by #27373

Comments

@alicnik
Copy link

alicnik commented Oct 21, 2022

Describe the bug

Providing an array of JSX elements, or an object containing JSX elements, as the value in a context provider causes Storybook to hang indefinitely. The UI may load but it cannot be interacted with once you click on the story with the context issue.

This only happens with arrays/objects. Passing a JSX element as the value in context works fine.

Example code of adding context in a story (with an array):

const Template = (args) => (
  <FooContext.Provider value={[<div>Hi</div>]}>
    <FooComponent {...args} />
  </FooContext.Provider>
);

This also happens if the context is placed in decorators, e.g. (with an object):

export default {
  ...csf,
  decorators: [
    (Story) => (
      <FooContext.Provider value={{ test: <div>Hi</div> }}>
        <FooComponent />
      </FooContext.Provider>
    )
  ]
}

One solution is to use the storybook-react-context add-on, however if there is something I have missed that is causing this issue I would welcome guidance on solving it without using an add-on.

To Reproduce

https://github.com/alicnik/storybook-jsx-array-context-bug

System

System:
    OS: macOS 12.6
    CPU: (8) x64 Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
  Binaries:
    Node: 16.18.0 - /usr/local/bin/node
    Yarn: 3.2.4 - /usr/local/bin/yarn
    npm: 8.19.2 - /usr/local/bin/npm
  Browsers:
    Chrome: 106.0.5249.119
    Firefox: 102.0.1
    Safari: 16.0
  npmPackages:
    @storybook/addon-docs: ^7.0.0-alpha.40 => 7.0.0-alpha.40 
    @storybook/addon-essentials: ^7.0.0-alpha.40 => 7.0.0-alpha.40 
    @storybook/addon-interactions: ^7.0.0-alpha.40 => 7.0.0-alpha.40 
    @storybook/addon-links: ^7.0.0-alpha.40 => 7.0.0-alpha.40 
    @storybook/react: ^7.0.0-alpha.40 => 7.0.0-alpha.40 
    @storybook/react-webpack5: ^7.0.0-alpha.40 => 7.0.0-alpha.40 
    @storybook/testing-library: ^0.0.13 => 0.0.13

Additional context

No response

@burdisal
Copy link

burdisal commented Oct 21, 2022

I am also running into this issue, passing an array of JSX elements as a prop to a component in Storybook. The following works well in a fresh Create React App, but hangs in Storybook, locking up my browser when I try to click any of the buttons.

One of my projects is not able to update Storybook because of #17413, and this component works without issue in that project (Storybook 6.3.12).

The only workaround I have found is sending the array of JSX as children, since sending it as a prop consistently causes Storybook to hang.

This issue looks like it also may be related to #17877.

My Component:

export default function Slideshow({ pages, page }) {
  return <div>{pages[page]}</div>;
}

And in my Storybook file:

const Template = (args) => {
  const [page, setPage] = useState(0);
  return (
    <Slideshow
      {...args}
      page={page}
      pages={[
        <button onClick={() => setPage(1)}>Go to page 2</button>,
        <button onClick={() => setPage(2)}>Go to Page 3</button>,
        <div>Page Three</div>,
      ]}
    />
  );
};

System

System:
  OS: MacOS 12.5.1
  CPU: 2.3 GHz 8-Core Intel Core i9
Binaries:
  Node: 16.1.9
  NPM: 7.24.2
Browsers:
  Firefox: 105.0.3
  Chrome: 106.0.5249.119
  Safari: 16.0
NPM Packages:
    "@storybook/addon-actions": "^6.5.12",
    "@storybook/addon-essentials": "^6.5.12",
    "@storybook/addon-interactions": "^6.5.12",
    "@storybook/addon-links": "^6.5.12",
    "@storybook/builder-webpack5": "^6.5.12",
    "@storybook/manager-webpack5": "^6.5.12",
    "@storybook/node-logger": "^6.5.12",
    "@storybook/preset-create-react-app": "^4.1.2",
    "@storybook/react": "^6.5.12",
    "@storybook/testing-library": "^0.0.13",

@alicnik
Copy link
Author

alicnik commented Oct 25, 2022

After some digging, it seems to be the same issue at heart as #12747. @burdisal perhaps the workaround there will work for you? Adding this to parameters in the story solved the issue for me:

docs: {
  source: { type: 'code' }
}

@burdisal
Copy link

@alicnik Thanks for the comment. Adding this does indeed solve this on my end.

@kostia-official
Copy link

@alicnik thanks, added to global parameters in preview.js and it worked

export const parameters = {
  docs: { source: { type: 'code' } },
};

@thexpand
Copy link

Setting the parameters.docs.source.type to code did the trick for me, but I can't understand why. I found this in the API docs:
https://storybook.js.org/docs/react/api/doc-block-source#type

By I still don't understand what's the difference between code and dynamic. Anyone care to explain?

@tmeasday
Copy link
Member

tmeasday commented Aug 8, 2023

The explanation for this issue is that react-element-to-jsx-string doesn't like it when you pass props that contain rendered elements.

See algolia/react-element-to-jsx-string#681

We already filter out pure elements and arrays that contain elements (#17482). It seems we still have an issue with objects that contain elements.

It sounds like maybe pinning the version of react-element-to-jsx-string to 14.3.2 may fix the issue. Why don't we just do that if it is unmaintained @shilman @IanVS ?

@emlai
Copy link

emlai commented Oct 26, 2023

The element doesn't have to be in a context to reproduce. See e.g. duplicate #17720.

@tmeasday
Copy link
Member

Can folks who are seeing this try pinning the version of react-element-to-jsx-string to see if it indeed does help? In package.json:

npm:

"overrides": {
   "react-element-to-jsx-string": "14.3.2"
}

yarn:

"resolutions": {
   "react-element-to-jsx-string": "14.3.2"
}

@emlai
Copy link

emlai commented Oct 30, 2023

@tmeasday Thanks, that seems to have fixed the issue.

@jonathan-chin
Copy link

@tmeasday this fixed it for me as well!

@tmeasday
Copy link
Member

@shilman shall we pin the version then?

shilman added a commit that referenced this issue Dec 23, 2023
shilman added a commit that referenced this issue Dec 23, 2023
@shilman
Copy link
Member

shilman commented Dec 23, 2023

@tmeasday I tried to reproduce here but couldn't #25312

@tmeasday
Copy link
Member

Hmm, yeah I am not seeing it in your example either. Can someone provide a working reproduction in 7.x?

@jleider
Copy link

jleider commented May 14, 2024

This also affects v8.1.0

@tmeasday
Copy link
Member

@jleider can you (a) provide a reproduction if possible? (b) confirm if pinning the version resolves it?

@jleider
Copy link

jleider commented May 14, 2024

@jleider can you (a) provide a reproduction if possible? (b) confirm if pinning the version resolves it?

@tmeasday

a) Its in a private repo and I don't have a simple reproduction case at this time. Although, I can see if we can make one for you.

b) Yes, the pinning of the version resolves it. We had previously had it pinned and I was hoping that the issue was resolved when upgrading storybook from v7 to v8 but the issue is still present.

@SuttonKyle
Copy link

@jleider can you (a) provide a reproduction if possible? (b) confirm if pinning the version resolves it?

Hi @tmeasday, I've managed to get a minimal working reproduction for the bug in Storybook 8, which you can see here: https://github.com/SuttonKyle/storybook-bug-repro

In this case, the response is very slow the first time you change the variant prop, and the second time you try to do so it freezes entirely. It seems to have to do with the fact that we have a jsx element nested within an object passed as props. If we do not pass args to the render function, the freeze does not occur. Please let me know if you have any questions or there's anything I can clarify for you! Thank you!

@tmeasday
Copy link
Member

Thank you for the reproduction @SuttonKyle. Can confirm both the bug and that pinning the version fixes it.

@shilman I think we should change the version of react-element-to-jsx-string we depend on. Do you agree?

@shilman
Copy link
Member

shilman commented May 27, 2024

@tmeasday I'm OK with that. Perhaps we can handle it properly later this year.

tmeasday added a commit that referenced this issue May 27, 2024
@tmeasday tmeasday linked a pull request May 27, 2024 that will close this issue
8 tasks
@aczekajski
Copy link

Btw my project is using Storybook 6.5.9 which uses react-element-to-jsx-string in version 14.3.4 and it also causes this problem.

Is there a plan to patch this problem in Storybook v6 as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.