storybook on react-native does not work with hmr (hot module reload) properly

Created on 18 Oct 2017  路  17Comments  路  Source: storybookjs/storybook

For HMR (hot module reload) to work, the root component has to be a class, as it seems.

I therefore added this to storybook/storybook.js :

const StorybookUIOrg = getStorybookUI({ port: 7007, onDeviceUI: true })

const StorybookUI = class extends Component {
  render() {
    return <StorybookUIOrg />
  }
}

AppRegistry.registerComponent('homestory', () => StorybookUI)

This used to work in the past, but with latest version, i just see the native ui menu and some warnings like:

"The prop url is marked as required in StoryView but it's value is null"

and

"The prop url is marked as required in OnDeviceUI, but it's value is null"

Edit: without the class above, there is no warning. But hot reload does not work. On the simulator it notifies about "hot reloading", but nothing changes.

Edit 2: if i change to a different story after hot reload and back, the changes are applied... So what's wrong?

I now switched back to live reload, HMR seems broken at the time beeing

react-native bug help wanted todo

Most helpful comment

I'm on "@storybook/react-native": "^4.0.0-alpha.25" and in order to get hot reloading working again after integrating storybook into my app I had to do the following.
Note the comment about react-native hot module loader must take a class.

/**
 * storybook/index.js
 **/
import React, { Component } from "react";
import { AppRegistry } from "react-native";
import { getStorybookUI, configure } from "@storybook/react-native";

import "./rn-addons";

// import stories
configure(() => {
  require("../App/Components/Stories");
}, module);

// Refer to https://github.com/storybooks/storybook/tree/master/app/react-native#start-command-parameters
// To find allowed options for getStorybookUI
const StorybookUIRoot = getStorybookUI({ port: 7007, onDeviceUI: true });

// react-native hot module loader must take in a Class - https://github.com/facebook/react-native/issues/10991
// https://github.com/storybooks/storybook/issues/2081
// eslint-disable-next-line react/prefer-stateless-function
class StorybookUIHMRRoot extends Component {
  render() {
    return <StorybookUIRoot />;
  }
}

// If you are using React Native vanilla and after installation you don't see your app name here, write it manually.
// If you use Expo you can safely remove this line.
// AppRegistry.registerComponent("ExportPro", () => StorybookUIRoot);

export default StorybookUIHMRRoot;

All 17 comments

@danielduan The issue is not resolved. I updated storybook to yesterdays version (3.2.14) and verified that the storybook index file matches this template https://github.com/storybooks/storybook/pull/2194 (I already had the base component as a class instead of a stateless function).

HMR still does not work in this setup. Any change to a file will trigger a refresh in the app, but it will crash with:

console.error: "(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.", 11

Object.console.error
    hashAssetFiles:55868:11
EventEmitter.addListener
    hashAssetFiles:166001:15
 (...)

by using the debugger i see that this happens in

 _this3._events.on('setCurrentStory', function (d) {
          return _this3._selectStory(d);
        });

Edit:

I am using CRNA (with expo) and i have added decorators to stories (e.g. ThemeProvider from styled-components).

Edit2: If I dismiss the error, storybook will show the startscreen again for a moment and go back to the story with the changes. Any further change to the components will have no effect and won't trigger HMR anymore.

Edit3: if i disable remote debugging, the memory leak error is still there, but otherwise HMR seems to work besides this bug: https://github.com/storybooks/storybook/issues/835

The decorators themselves might break HMR if it's a stateless functional component. Our event emitter probably needs some work too.

If you have time to dig through this, we'd love some help on a PR.

Do you have a repo so I can try to reproduce this? @macrozone

I just tried in our CRNA example and it seems to work:

7:14:27 PM: [React Transform HMR] Patching Welcome

7:14:45 PM: [React Transform HMR] Patching Welcome

I found this issue while trying to figure out why 3.3.12 is not working with HMR.
It does print in the console as expected, however the screen on the device doesn't get updated.
See the video of the issue. Repository is fresh from GitHub - bootstraped using yarn bootstrap.


Update
After playing around a bit found that the issue is actually only happens with static fields inside class...
Thinking about it, it does make sense that it doesn't work as it essentially patches constructor which won't be executed unless component is remounted.
Found that moving styles into separate file fixes the problem. Hopefully, it will help people facing similar issue to diagnose it.

it's hard to tell what's wrong with hmr and react-native. It works for some time, but starts to get slower and slower, eats cpu on both the device and the computer, throwing errors like the dreaded "possible event emitter leaked" and now kills the server eventually (see https://github.com/storybooks/storybook/issues/2923)

So it basically "works" but extremly unreliable and i therefore wonder if anyone successfully uses it on real projects

I too am getting this error.
For now I've added this hack to my init storybook function to at least delay the error for a bit :)
I'll report back if it works or not.

require('events').EventEmitter.defaultMaxListeners = 200;

I'm using a global decorator along with create react native app, typescript and storyshots.
Happy to attempt a PR if anyone can suggest the best place to look

I'm on "@storybook/react-native": "^4.0.0-alpha.25" and in order to get hot reloading working again after integrating storybook into my app I had to do the following.
Note the comment about react-native hot module loader must take a class.

/**
 * storybook/index.js
 **/
import React, { Component } from "react";
import { AppRegistry } from "react-native";
import { getStorybookUI, configure } from "@storybook/react-native";

import "./rn-addons";

// import stories
configure(() => {
  require("../App/Components/Stories");
}, module);

// Refer to https://github.com/storybooks/storybook/tree/master/app/react-native#start-command-parameters
// To find allowed options for getStorybookUI
const StorybookUIRoot = getStorybookUI({ port: 7007, onDeviceUI: true });

// react-native hot module loader must take in a Class - https://github.com/facebook/react-native/issues/10991
// https://github.com/storybooks/storybook/issues/2081
// eslint-disable-next-line react/prefer-stateless-function
class StorybookUIHMRRoot extends Component {
  render() {
    return <StorybookUIRoot />;
  }
}

// If you are using React Native vanilla and after installation you don't see your app name here, write it manually.
// If you use Expo you can safely remove this line.
// AppRegistry.registerComponent("ExportPro", () => StorybookUIRoot);

export default StorybookUIHMRRoot;

Hey @jqn, so to be clear you had to create StorybookUIHMRRoot even though we already create it in getStorybookUI?

Yes I did. The hot reload was broken with the default install configuration.

@jqn This worked for me as well

We鈥檝e released a brand new @storybook/react-native with a bunch of core improvements. It鈥檚 available in the latest 5.1-alpha on next and has been verified by several RN users on their existing apps. It should fix a bunch of compatibility issues, especially if you鈥檙e using the web server feature. Please give it a try and comment here if it fixes your problem. Migration instructions available here: https://github.com/storybooks/storybook/blob/next/MIGRATION.md#react-native-server

@macrozone @odino @b3ngineer @maxhungry @tonyxiao @Bardiamist @danielduan @EskelCz @Maxim-Filimonov @axelnormand @jqn @jjm340 @iamolegga @FunkSoulNinja @miltoneiji @Gongreg

Still not working on 5.1 for me

@stereodenis try 5.2-beta? 馃檲

@shilman 5.2-beta.7
image

Sadly there was no effort done to fix hmr

React Native 0.61 has a new reload format, so closing this issue. The new issue is #7916

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ZigGreen picture ZigGreen  路  3Comments

zvictor picture zvictor  路  3Comments

shilman picture shilman  路  3Comments

shilman picture shilman  路  3Comments

tirli picture tirli  路  3Comments