Storybook: Controls with decorator always remount from root

Created on 26 Aug 2020  路  5Comments  路  Source: storybookjs/storybook

Describe the bug
With decorator, when you change some args by controls, all DOM inside iframe are remounted and so css transition not working

To Reproduce
https://github.com/jwoo0122/storybook-test

  1. Clone this repository.
  2. npm run storybook
  3. Access localhost:6006
  4. Go to Button story, and toggle primary in control panel.

Expected behavior
CSS transition should works.

Screenshots
This is the expected behavior (tested without decorator).
ezgif com-video-to-gif-2

And this is an actual behavior (tested with decorator).
ezgif com-video-to-gif-3

Code snippets
Decorator used to test is this. You can find this in Button.stories.js from the repo I wrote into 'To Reproduce' section.

Story => <Story />

System:

Environment Info:

  System:
    OS: macOS 10.15.6
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 12.18.0 - ~/.nvm/versions/node/v12.18.0/bin/node
    npm: 6.14.4 - ~/.nvm/versions/node/v12.18.0/bin/npm
  Browsers:
    Chrome: 84.0.4147.135
    Edge: 84.0.522.63
    Firefox: 79.0
    Safari: 13.1.2
  npmPackages:
    @storybook/addon-actions: ^6.0.18 => 6.0.18 
    @storybook/addon-controls: ^6.0.18 => 6.0.18 
    @storybook/addon-essentials: ^6.0.18 => 6.0.18 
    @storybook/addon-links: ^6.0.18 => 6.0.18 
    @storybook/node-logger: ^6.0.18 => 6.0.18 
    @storybook/preset-create-react-app: ^3.1.4 => 3.1.4 
    @storybook/react: ^6.0.18 => 6.0.18 

Additional context
jwoo0122/storybook-test is configured by the step below.

npx create-react-app storybook-test
cd storybook-test
npx -p @storybook/cli sb init
npm i -D @storybook/addon-controls

And add decorator to Button.stories.js and preview.js (global decorators).

P2 controls react bug has workaround tracked

Most helpful comment

@jwoo0122 FYI it does work if the decorator is Story => Story().

I have no idea why React is doing this. My only explanation is that from React's perspective, <Story/> is changing when the args change.

My mental model of <Story /> is that React creates an element of the form { type: Story, props: {} } -- and when it does the VDOM diff to decide whether to recreate the DOM node it simply considers the equality of the type field. The Story function doesn't change when the args change, so I am missing something (you can put a break point in _renderMain to see that).

All 5 comments

Still reproduced in 6.0.20

Possibly related: https://github.com/storybookjs/storybook/issues/10616

@tmeasday can you take a look?

@jwoo0122 FYI it does work if the decorator is Story => Story().

I have no idea why React is doing this. My only explanation is that from React's perspective, <Story/> is changing when the args change.

My mental model of <Story /> is that React creates an element of the form { type: Story, props: {} } -- and when it does the VDOM diff to decide whether to recreate the DOM node it simply considers the equality of the type field. The Story function doesn't change when the args change, so I am missing something (you can put a break point in _renderMain to see that).

Is there a workaround for this? Right now when I add this to preview.js all transitions break:

export const decorators = [
  (Story) => <ThemeProvider theme={light}><GlobalFonts/><Story/></ThemeProvider>
]

Ah nvm, figured it out. This fixes it:

export const decorators = [
  (Story) => <ThemeProvider theme={light}><GlobalFonts/>{Story()}</ThemeProvider>
]
Was this page helpful?
0 / 5 - 0 ratings