Storybook: Using react hooks + storybook hooks between stories and decorators break SB

Created on 18 Feb 2020  路  6Comments  路  Source: storybookjs/storybook

Describe the bug

The error: Storybook preview hooks can only be called inside decorators and story functions

To Reproduce
Steps to reproduce the behavior:

  1. Write a story with just a div.
  2. Write two decorators.
  3. Write the first decorator with useParameter and some react hooks.
  4. Write the second decorator with just rendering the story as a react component.
  5. See the error.

Expected behavior
To not have this issue.

Code snippets

// Component.story.tsx

export default {
  title: 'New story',
  decorators: [hooksDecorator, justDecorator],
};

export function initial() {
  return <div>Hiii</div>;
}

// decorators.tsx
export function hooksDecorator(Story) {
  const someBool = useParameter<boolean>('bool');
  const [state, setState] = useState(someBool);

  useEffect(() => {
    setTimeout(() => {
      setState(someBool || true);
    }, 100);
  }, [someBool]);

  return <Story />
}

export function justDecorator(Story) {
  return <Story />
}

System:

    OS: Linux 4.15 Ubuntu 18.04.4 LTS (Bionic Beaver)
    CPU: (4) x64 Intel(R) Core(TM) i7-4510U CPU @ 2.00GHz
  Binaries:
    Node: 12.14.1 - ~/.nvm/versions/node/v12.14.1/bin/node
    Yarn: 1.21.1 - /usr/bin/yarn
    npm: 6.13.4 - ~/.nvm/versions/node/v12.14.1/bin/npm
  Browsers:
    Chrome: 80.0.3987.106
    Firefox: 74.0b4
  npmPackages:
    @storybook/addon-actions: 5.3.13 => 5.3.13 
    @storybook/addon-docs: 5.3.13 => 5.3.13 
    @storybook/addon-knobs: 5.3.13 => 5.3.13 
    @storybook/preset-typescript: 1.1.0 => 1.1.0 
    @storybook/react: 5.3.13 => 5.3.13

Extra information:
You don't need to really use the parameter data nor the react hooks' data to get to this error state. Just because you're rendering the story as a component will produce this situation.

But something to note: if the decorators are reordered and the hooksDecorator is in the last place, the bug won't happen. Also, if hooksDecorator is first and the rest just render the story as a function, it won't happen either.

addons bug todo

Most helpful comment

go away stale bot.

All 6 comments

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

go away stale bot.

@shilman I seem to be having the same issue, has anyone found a solution to this?

I'm using Storybook v6.0.28, and all packages are up to that version.

A short update on this one!

It is indeed the case that if the decorators are reordered, and the one using hooks is left as the last one, it just works.

It might not be the case when you have more than one decorator that is using hooks, I haven't tested that as my use case does not require it.

cc @tmeasday

I don't think it is possible to use Storybook hooks outside of the initial render cycle -- in the example above when the set state runs, the SB hook is going to run again and I don't think that's going to work.

I don't think decorators should combine react+sb code in this way. My advice would be make the react hook code into a component and render that component in a simpler decorator.

Was this page helpful?
0 / 5 - 0 ratings