storybook: Storybook not compatible with React hooks
Describe the bug
Attempting to render a react component that uses hooks into a storybook staging environment throws an error Hooks can only be called inside the body of a function component.
To Reproduce Steps to reproduce the behavior:
- Create a react component that uses hooks
- Import & render the component in storybook
Expected behavior Storybook should be able to display React components that use hooks.
Code snippets
Component code
import React, { useState } from "react";
export default function ColorChanger() {
const [color, setColor] = useState("#000");
const randomColor = "#" + Math.floor(Math.random() * 16777215).toString(16);
return (
<div style={{ color }} onClick={() => setColor(randomColor)}>
Color is: {color} (click to change)
</div>
);
}
Note, this code is working on codesandbox: https://codesandbox.io/s/n5rmo77jx0
System:
- Browser: Firefox
- Framework: React
- Version: 4.0.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 25
- Comments: 73 (25 by maintainers)
For my, it worked:
react e react-dom: 16.8.1.
Try:
in your .config file.
This should do the trick - for now.
So I ran into this issue using CRA 2.1.1 with typescript on the 4.1.0-alpha.8 version of
@storybook/reactand hooks and it ended up coming down to the fact that the package includes it’s own local copy of React so when the hook is called it can’t find theReactSharedInternals.ReactCurrentOwner.currentDispatcherinstance. As silly as it felt, I just updated my npm scripts to the following:And everything seemed to work. Maybe react/react-dom need to be peer-dependencies of
@storybook/reactinstead of regular deps?I tried the
react-hot-loadersetConfig thing only to find that react-hot-loader wasn’t installed in the first place. Maybe this is a change with the 4.1 alpha but I’m new to storybook in general so I wouldn’t know.I also had this problem, and tracked it down (as someone else said before) to the fact that Storybook uses a different instance of React (one in my workspace node_modules, and one in the storybook node_modules, I’m using Yarn Workspaces, monorepo).
I tried the package.json resolution trick, to no avail.
I got it working though by tweaking the webpack.config by using aliases and forcing both react and react-dom to be used from the root node_modules:
and then in your config :
Hope that helps.
This didn’t work for me, I get the exact same error with or without it.
I had the same problem but got it working.
example=>Example<ColorChanger />and notColorChanger()I did also update the react-dom package to 16.7.0-alpha.0 before I tried any of this, so perhaps, if you haven’t already, give that a go as well.
@Amolang 😄 gotcha, yeah this issue is only happening for me in when using hooks with storybook, which is why I filed the issue for storybook specifically. Will update the title to make it more clear that it’s storybook specific.
@Amolang Pretty sure I’m doing all of the same steps. The specific error message that I’m seeing leads me to believe the error isn’t a result of one of those cases.
Good thought regarding react-dom—I thought that might be it, but I updated it and still go the same error 😕
Yes
alpha.2version or 16.7.0-alpha.2.4 in terms ofhot-loader/react-dom@jgoux Yea, this is latest gotcha 😄 React 16.7.0 was released without hooks and if you are not careful, it can break apps. See more info here: https://reactjs.org/blog/2018/12/19/react-v-16-7.html#why-is-this-bugfix-a-minor-instead-of-a-patch
@theKashey I had the exact same problem as in OP and by forcing react versions it was gone. I assume it’s because Storybook uses a hook-less version of React to drive the rendering. However, when you import eg.
useState, it’s a React 16.7 and it looks for the dispatcher which is most likely in some different space. I don’t know internals that much.From all these comments this workaround makes the most sense to me. I don’t get why would hot loader be involved at all. I am on Storybook 4.1.2 and
react-hot-loaderis not even installed as a dependency. If some people have it innode_modulesit’s most likely for different reasons so any kind of hacking webpack config can doubtfully work.Nvm, I was using hooks inside of the
.add('with ...', () => { ... return (<Component></Component>) }part which is a no go, my bad. Instead I’m creating a function outside of it and using it like.add('with ...', () => (<ComponentWithHooks></ComponentWithHooks>))to test it with hooks.Wrapping the story in a div worked for me
I hit the same problem using a hooks based component, and after some experimentation found the cause of it…
My story markup looked like this
It appears that a normal
<div>tag is what confuses the matter, and the solution is to make sure that the wrapping component is a React component, and not just a regular html tag. So I defined aWrappercomponent like this:and then changed my story markup to be like this
Problem solved, and no need to import any special libraries to make it work.
@JasonTheAdams Here I describe a simple way to use hooks and still retain the jsx. It only works for child components though
https://mobile.twitter.com/HipsterSmoothie/status/1107182717467156484
My co worker built a tiny library with a hooks like API that he just released that is also jsx friendly. This is probably your best bet to get jsx and interactivity
https://github.com/adierkens/storybook-addon-state
I guess this should be closed then @ilias-t
This should work with the 4.1 release. According to the release notes, Storybook now uses the React versions from the project for the actual preview (and whatever it uses internally for the manager).
That means, if you update Storybook to 4.1 or later, and React + React-DOM to 16.8.0-alpha.1, you should have Hooks working in Storybook.
The fix I’ve finally found is to force a specific version of @hot-loader/react-dom during the installation of the patch.
My current version of react-dom is 16.7.0-alpha.2, so I just did:
and my .storybook/webpack.config.js is:
And now hooks are working fine inside storybook!
React-Hot-Loader 4.6.0 should work with hooks out of the box. https://medium.com/@antonkorzunov/react-hot-loader-4-6-41f3ce76fb08