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

Hot reloading (HMR) not working with functional components #10991

Closed
thedgbrt opened this issue Nov 17, 2016 · 50 comments

Comments

@thedgbrt
Copy link

commented Nov 17, 2016

Description

Hot reloading doesn't work on functional components. The "hot loading" message appears, but the changes don't show up.

Reproduction

react-native init test
cd test

Open index.android.js and replace :

export default class test extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Double tap R on your keyboard to reload,{'\n'}
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  }
}

with

const test = () => (
  <View style={styles.container}>
    <Text style={styles.welcome}>
      Welcome to React Native!
    </Text>
    <Text style={styles.instructions}>
      To get started, edit index.android.js
    </Text>
    <Text style={styles.instructions}>
      Double tap R on your keyboard to reload,{'\n'}
      Shake or press menu button for dev menu
    </Text>
  </View>
);

Enable hot reloading, reload the app and try to make changes.

Additional Information

  • React Native version: 0.37.0
  • Platform: Android (didn't try ios)
  • Operating System: Windows

@thedgbrt thedgbrt referenced this issue Nov 17, 2016

Closed

Fix hot reloading storybook #8

2 of 3 tasks complete
@lacker

This comment has been minimized.

Copy link
Contributor

commented Nov 30, 2016

@martinbigio is this a known behavior of HMR in React Native?

@hey99xx

This comment has been minimized.

Copy link

commented Dec 3, 2016

Reading https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html

The default transformer that comes with React Native uses the babel-preset-react-native, which is configured to use react-transform the same way you'd use it on a React web project that uses Webpack.

Looks like that transformer library historically had issues with hot reloading functional components according to gaearon/babel-plugin-react-transform#57

I can guess both iOS and Android will be broken, this seems purely like a limitation of the JavaScript transformation process.

@tlvince

This comment has been minimized.

Copy link

commented Dec 5, 2016

HMR with stateless functional components throws "Maximum call stack exceeded" for me:

Enabling JS debugging yields:

99 index.js:81 [React Transform HMR] Patching App
ExceptionsManager.js:63 Maximum call stack size exceeded
handleException @ ExceptionsManager.js:63
handleError @ InitializeCore.js:114
reportFatalError @ error-guard.js:44
guard @ MessageQueue.js:48
callFunctionReturnFlushedQueue @ MessageQueue.js:107
(anonymous) @ debuggerWorker.js:71
index.js:81 Uncaught RangeError: Maximum call stack size exceeded
    at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:5867:9
    at wrapWithProxy (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:5872:3)
    at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:102821:1260
    at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:102821:1348
    at loadModuleImplementation (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:188:1)
    at guardedLoadModule (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:133:13)
    at _require (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:124:1)
    at accept (http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:285:1)
    at http://localhost:8081/index.android.bundle?platform=android&dev=true&hot=true&minify=false:243:25
    at Array.filter (native)

Note it loops on [React Transform HMR] Patching App and eventually throws. The same thing works if I rewrite my components to use classes.

Is it possible to switch to gaearon/react-hot-loader (v3) perhaps?

Connects #7288, #8465.

@mattread90

This comment has been minimized.

Copy link

commented Dec 9, 2016

@tlvince I was experiencing the same issue and fixed it after finding and removing a circular dependency in my project. I noticed that the "Maximum call stack exceeded" was only being thrown when I edited files under a certain level in my "dependency tree".

Not sure it's correct behaviour for the Hot Loading but it could be what is happening in your case too.

@Venryx

This comment has been minimized.

Copy link
Contributor

commented Dec 23, 2016

Just wanted to mention I have a similar issue here: gaearon/react-transform-hmr#82

@mattread90 Do you have your project in a public repo, so I can see the commit where you solved the issue?

Because it seems odd to me that you could have a circular dependency, and yet only have it cause problems with the hot-reloading, as opposed to the initial load.

@sospedra

This comment has been minimized.

Copy link

commented Dec 28, 2016

+1 any news on the horizont?

@mattread90

This comment has been minimized.

Copy link

commented Dec 28, 2016

@Venryx I don't, but I've recreated the issue here. You should be able to see the app render correctly on initial load, but will throw the "Maximum call stack exceeded" exception on edits to certain files.

@astraldragon

This comment has been minimized.

Copy link

commented Jan 24, 2017

I'm not seeing the infinite loop, but hot reloading isn't working. I update my styles and they aren't updated on the simulator.

@shahen94

This comment has been minimized.

Copy link

commented Feb 19, 2017

+1

@ferologics

This comment has been minimized.

Copy link

commented Mar 6, 2017

Especially painful when working with react-navigation b/c it's almost all composed of functional components that don't reload on save. I think this is a solid dev experience pain point - cc @grabbou is there anything to be done here?

@grabbou

This comment has been minimized.

Copy link
Collaborator

commented Mar 6, 2017

Not sure there's anything related to react-navigation to be done here. The issue exists in React Native.

@migueloller

This comment has been minimized.

Copy link

commented Mar 6, 2017

The reason why React Native HMR doesn't work with stateless functional components is because it uses react-transform-hmr which doesn't support them (it says so in the README).

React Native will either have to use something like react-hot-loader (which I'm not sure it can since it doesn't use Webpack but could still implement some of its features in the packager) or roll up their own solution that works for stateless functional components.

@dylanpyle

This comment has been minimized.

Copy link

commented Mar 15, 2017

I'm seeing the same issue with PureComponent. Let me know if that's unrelated and I can file a different issue — I'm not clear on why #9152 was closed.

@n1ru4l

This comment has been minimized.

Copy link
Contributor

commented Mar 21, 2017

I can confirm the issue @tlvenn has when I use circular dependencies.
The example from @mattread90 helped me to fix the issue.
However I can not confirm that stateless functional components are not updating - Mine are updating without problems - and almost every component I use is a stateless function component.

@grabbou grabbou referenced this issue Mar 31, 2017

Closed

Get HMR running #2

@codebymikey

This comment has been minimized.

Copy link

commented Apr 3, 2017

+1

1 similar comment
@kristojorg

This comment has been minimized.

Copy link

commented Apr 8, 2017

+1

@kristojorg

This comment has been minimized.

Copy link

commented Apr 8, 2017

HMR appears to work for all components that are beneath at least one class component. So I made my root component a class, and now HMR is still working even with SFCs below. Hope this helps someone!

@FenrirWillow

This comment has been minimized.

Copy link

commented Apr 13, 2017

What @kristojorg said is true - the HMR does indeed detect changes functional components and reloads the app correctly, however there is a caveat to this: it will reload the closest parent class based component, not the component itself. So if you make your root component a class based one, every time you change one of your functional components it will reload from the root down, instead just the component you changed.

@kristojorg

This comment has been minimized.

Copy link

commented Apr 13, 2017

Yep that's a good point I forgot to mention. Not sure why it's working this way. Is it using the same implementation as create react app?

@irrigator

This comment has been minimized.

Copy link

commented Apr 29, 2017

I tested it on 0.43.4 and can confirm that it does not work for either functional component or PureComponent.

@lsps9150414

This comment has been minimized.

Copy link

commented May 10, 2017

If I do (inside a class component):

renderSomeText = () => {
  console.log('render Some Text');
  return (<Text>Some Text</Text>);
}

render() {
  console.log('render');

  return (
    <View>
      {this.renderSomeText()}
    </View>
  };
}

On hot reload, console.log('render'); is called but not console.log('render Some Text');.
Is this relevant to this issue?

@pie6k

This comment has been minimized.

Copy link

commented Jun 19, 2017

Any update?

@codebymikey

This comment has been minimized.

Copy link

commented Jun 19, 2017

@lsps9150414

renderSomeText = () => {
  console.log('render Some Text');
  return (<Text>Some Text</Text>);
}

doesn't hot reload because of the way the code is transpiled into the constructor before hot reload can proxy it. I can't find the source for it anymore, but can confirm from personal experience.

constructor(props) {
    super(props);
    this.renderSomeText = this.renderSomeText.bind(this);
  }
function renderSomeText(){
  console.log('render Some Text');
  return (<Text>Some Text</Text>);
}

works differently, you can run your app in debug mode and step through it to see what it's doing when hot reload is enabled.

https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html#react-components might help you understand how it works better.

@martinezguillaume

This comment has been minimized.

Copy link
Contributor

commented Jul 18, 2017

@mattread90 Thank you so much ! I remove all circular dependencies from my app and it works ! 😍

@bvic23

This comment has been minimized.

Copy link

commented Jul 26, 2017

@pie6k Try my babel plugin https://github.com/bvic23/babel-plugin-functional-hmr until the issue is fixed.

@mobdim

This comment has been minimized.

Copy link

commented Jan 10, 2018

@mindwards After upgrade to 0.52.0 this solution not working.
Issue: https://github.com/bvic23/babel-plugin-functional-hmr/issues/9

@grit96

This comment has been minimized.

Copy link

commented Jan 26, 2018

@levibuzolic did you find a workaround for HMR with auto-bind functions?

@Gyran

This comment has been minimized.

Copy link
Contributor

commented Feb 8, 2018

For those who are using https://github.com/bvic23/babel-plugin-functional-hmr a fix as been release for React Native 0.52+

@jrwpatterson

This comment has been minimized.

Copy link

commented Nov 29, 2018

did this get fixed I still have it and with react-native 57 on babel7 the above plugin isn't working for me?

@jrwpatterson

This comment has been minimized.

Copy link

commented Mar 26, 2019

did this get fixed in 59?

@Jensenks

This comment has been minimized.

Copy link

commented Apr 25, 2019

@jrwpatterson It's still not working for me on 0.59

@zlv-thisF

This comment has been minimized.

Copy link

commented Apr 30, 2019

+1

@asherccohen

This comment has been minimized.

Copy link

commented May 14, 2019

This is still not working, I confirm that functional component break the screen:
"react-native": "0.57.5",
"react": "16.6.1",

I have to constantly reload by hand because hot reload crashes and displays red screen.

Capture

@rardoz

This comment has been minimized.

Copy link

commented May 21, 2019

I think it has gotten worse actually. Im seeing it crash even when HMR is off and live reloading is enabled. Every save, crash.

@vanGalilea

This comment has been minimized.

Copy link

commented May 23, 2019

Is a there a fix available, which still enables to use react hooks and HMR?

@zeevl

This comment has been minimized.

Copy link

commented May 23, 2019

What is working for me is to use class components for screens. Then, any child components can be functional w/ hooks, and HMR still works.

Also, if you're using mobx, make sure you're using https://github.com/mobxjs/mobx-react-lite

@rardoz

This comment has been minimized.

Copy link

commented May 23, 2019

@zeevl I converted all of my views into class components, but still the same. Save, crash. I also cleared the builds, reinstalled everything, and upgraded everything to the latest version. I do have providers that use hooks that are wrapping the views within the app.js. Could these be what are killing everything? I am using the useContext hook.

So the app.js looks sort of like this

class extends Component {
    render(){
      return (
         <MyProvider> // function component with useDispatch hook
            <MyNavigationComponentWithMyViews />
         </MyProvider>
      )
    }
}
@gaearon

This comment has been minimized.

Copy link
Member

commented Jun 28, 2019

This has been fixed on master with a new implementation we're calling Fast Refresh.
https://mobile.twitter.com/reactnative/status/1144629612921720833

It will be a part of the 0.61 release. I'm going to close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.