react-native: When Hot reloading is enabled, Requiring a component fails with TypeError: Attempting to change the getter of an unconfigurable property

Description

Hot reload doesn’t work with named exports like that: components/index.js

import Comp1 from './Comp1'
import Comp2 from './Comp2'
export { Comp1, Comp2 }

Both Comp1 and Comp2 are functional components.

The following error is thrown when hot reloading is enabled and I change something in Comp1:

Requiring module “app/Navigator.js”, which threw an exception: Error: Requiring module “app/components/index.js”, which threw an exception: TypeError: Attempting to change the getter of an unconfigurable property.

If I change the component into a class based one it works.

Reproducible Demo

Create a new project with react-native init, make a components directory with one functional component:

import React from 'react'
import { Button } from 'react-native'

const MyButton = props => <Button {...props} />
export default MyButton

and an index.js file

import MyButton from './MyButton'
export { MyButton }

and use it in App.js

import { MyButton } from './components'

...

<MyButton title="PressMe" onPress={this.handlePress} />

Now, enable hot reloading, go to MyButton and change something (optional) and save it. You should get a similar error.

simulator screen shot - iphone x - 2018-12-10 at 23 47 49

Environment

React Native Environment Info: System: OS: macOS 10.14 CPU: (8) x64 Intel® Core™ i7-4770HQ CPU @ 2.20GHz Memory: 735.79 MB / 16.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 8.11.3 - ~/.nvm/versions/node/v8.11.3/bin/node Yarn: 1.12.3 - /usr/local/bin/yarn npm: 6.4.1 - ~/.nvm/versions/node/v8.11.3/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1 Android SDK: API Levels: 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 Build Tools: 23.0.1, 23.0.3, 25.0.2, 26.0.3, 27.0.0, 27.0.1, 27.0.2, 27.0.3, 28.0.2, 28.0.3 System Images: android-23 | Intel x86 Atom, android-23 | Intel x86 Atom_64, android-23 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom_64, android-25 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom_64, android-26 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom IDEs: Android Studio: 3.2 AI-181.5540.7.32.5014246 Xcode: 10.1/10B61 - /usr/bin/xcodebuild npmPackages: react: 16.6.1 => 16.6.1 react-native: 0.57.7 => 0.57.7 npmGlobalPackages: react-native-cli: 2.0.1 react-native-git-upgrade: 0.2.7

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 47
  • Comments: 38 (5 by maintainers)

Most upvoted comments

+1 It’s really annoying. RN 0.57.8

I have verified this is fixed on master. The fix is part of Fast Refresh which is expected 0.61.

Still happening on RN 0.58.x and 0.59.x

I can confirm it happens for me when I’m using index exporters in my folders structure eg

I have src/ui/tasks/index.ts

export * from './CheckableTask';
export * from './Editor';
export * from './Task';
export * from './EditableTask';
export * from './NoTasks';

For ‘better importing experience’. In this case, hot reloading crashes with TypeError: Attempting to change the getter of an unconfigurable property

Not sure, but I’d say this is quite popular pattern to group imports like this, but it makes hot reloading not usable at all in rn

this workaround works for me

import C from './Currency;

const CurrencyHelper = C;

export {
  CurrencyHelper
}

Experiencing the same issue.

Hey, thanks @janicduplessis for the fix, it works great but for some reason it breaks the react-native-vector-icons library (which I’m sure many of us may be using)

As soon as you enable the plugin, you get an error saying 'Native Module cannot be null' referring to PushNotificationsIOS. Linking that solves that issue but causes another one along the lines BackAndroid is deprecated, use BackHandler instead (see image for below) despite BackAndroid never being referenced in the library

There seems to be a direct correlation between the plugin/fix and the react-native-vector-icons library. Remove either the plugin or the library will solve the issue.

If anybody knows anything about this that would be great!

Screenshot 2019-05-29 at 16 36 02

I found that hot reload is not working with “function component” because when i change it to “class component”, it’s woking fine. I don’t know why 😕

Seems like the issue is related to some incompatibility with the way hot reloading works and the namespace re-export babel transform. As a workaround you can enable loose mode and it will use a simple assignment instead of Object.defineProperty and fix the error.

Add this @babel/plugin-transform-modules-commonjs config in your .babelrc or babel.config.js file.

module.exports = {
  presets: [
    'module:metro-react-native-babel-preset',
  ],
  plugins: [
    [
      '@babel/plugin-transform-modules-commonjs',
      {
        strictMode: false,
        allowTopLevelThis: true,
        loose: true,
      },
    ],
  ],
};

Please send all reproducing cases you have to https://github.com/facebook/react-native/issues/18899 as projects I can clone. The more, the better. I’ll go through them and verify they’re fixed. This is the chance to get them working.

Having the same issue, as hooks become more widespread not being able to hot reload functional components will become more of an issue…

Still happening on 0.59.5

We’ve completely revamped how this feature works: https://github.com/facebook/react-native/issues/18899#issuecomment-506881769.

I’ll see whether we fixed this issue. If not, I’ll fix it.

It’s amazing to me that this issue still exists. I’m on RN 0.59.8 , and unfortunate none of the suggestions above worked for me. The only way I manage to dodge this error is by using one import in the index.js file - which mostly is not the use case.

Having the same issue, as hooks become more widespread not being able to hot reload functional components will become more of an issue…

for me the solution given by @janicduplessis only gave me error. Tried deleting all modules, reseting etc.

My versions is RN 0.59.5, babel core 7.4.0.

Is this a version thing? Anyone else tried that?

Screenshot 2019-04-25 at 23 57 58

@ospfranco Make sure to start the packager with --reset-cache after making the change. If that doesn’t work I’m not sure, your config looks good.

Just for clarity’s sake, you need to apply the configuration for the plugin on it’s own array, here is my babel.config.js file:

  "presets": ["module:metro-react-native-babel-preset"],
  "plugins": [
    "@babel/plugin-transform-runtime",
    ["@babel/plugin-transform-modules-commonjs",
      {
        strictMode: false,
        allowTopLevelThis: true,
        loose: true,
      }
    ]
  ]
}

However, even though now simulator does not crash, the changes I make are not being applied, I tried using https://github.com/bvic23/babel-plugin-functional-hmr, but it doesn’t seem to work either, any suggestions?

Happens for me when exporting multiple functional components from one file and using an index exporter, e.g.:

export const Component = props => (
    <View><Text>Component</Text></View>
)

export const OtherComponent = props => (
    <View><Text>Other Component</Text></View>
)

Then exporting the components in an index file

export * from './Components'

Exporting just one of the components from the first file works fine

There is the same problem. From behind it a new project started on Flutter. There is no such problem with Flutter.