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

ReferenceError: Property 'React' doesn't exist after upgrade react-native to 0.64.0 #646

Closed
chengsokdara opened this issue Mar 14, 2021 · 13 comments

Comments

@chengsokdara
Copy link

Do you want to request a feature or report a bug?
Report a bug and suggestion to fix it.

What is the current behavior?
I try to upgrade to 0.64.0 from 0.63.4 which include react 17 with the New JSX Transform.
After I remove React import from all my component files.
I got below error when running the app yarn android with yarn start --reset-cache

ReferenceError: Property 'React' doesn't exist

This error is located at:
    in App (at renderApplication.js:47)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:107)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:134)
    in AppContainer (at renderApplication.js:40), js engine: hermes
ReferenceError: Property 'React' doesn't exist

This error is located at:
    in App (at renderApplication.js:47)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:107)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:134)
    in AppContainer (at renderApplication.js:40), js engine: hermes

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

  1. initialize fresh react-native 0.63.4 npx react-native init AwesomeTSProject --template react-native-template-typescript
  2. use upgrade-helper to upgrade to react-native 0.64.0
  3. remove any import React from 'react'; from component file.
  4. error will show ReferenceError: Property 'React' doesn't exist

What is the expected behavior?
As from React blog about New JSX Transform, it needs additional config in babel.config.js

// If you're using @babel/plugin-transform-react-jsx
{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}
  • After I add this into my babel.config.js and yarn start --reset-cache and yarn android the error was gone.

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

  • metro-react-native-babel-preset 0.64.0
  • node 14.16.0
  • yarn 1.22.5
/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
};

@klandell
Copy link

klandell commented Mar 14, 2021

I'm having a similar issue using typescript and "jsx": "react-jsx", in tsconfig.json.

Setting:

{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "runtime": "automatic"
    }]
  ]
}

Gives me the error:
Duplicate __self prop found. You are most likely using the deprecated transform-react-jsx-self Babel plugin. Both __source and __self are automatically set when using the automatic runtime. Please remove transform-react-jsx-source and transform-react-jsx-self from your Babel config.

@moonlight8978
Copy link

moonlight8978 commented Mar 15, 2021

Because, metro-react-native-babel-preset includes @babel/plugin-transform-react-jsx by default. If you add it to plugins, it would be duplicated.

if (!options.useTransformReactJSXExperimental) {
extraPlugins.push([require('@babel/plugin-transform-react-jsx')]);
}

But set useTransformReactJSXExperimental: true is not enough. To use new JSX transformation, you have to pass runtime: 'automatic' to @babel/plugin-transform-react-jsx too (runtime is classic by default).
https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html#manual-babel-setup

So you might want to change your babel.config.js to:

module.exports = {
  presets: [['module:metro-react-native-babel-preset', { useTransformReactJSXExperimental: true }]],
  plugins: [
    [
      '@babel/plugin-transform-react-jsx',
      {
        runtime: 'automatic',
      },
    ],
  ]
}

@darrylyoung
Copy link

darrylyoung commented Mar 15, 2021

I'm having the same issue:

ReferenceError: Can't find variable: React

Thanks for the suggestion, @moonlight8978, but I unfortunately still can't get mine working. I originally started my project with Expo but have since ejected to bare workflow. My babel.config.js, up until now, looked like this:

module.exports = function (api) {
 api.cache(true)

 const presets = ['babel-preset-expo']
 const plugins = ['react-native-reanimated/plugin']

 return {
   presets,
   plugins,
}

Since updating to React Native 0.64 this morning, and following the steps in the New JSX Transform docs (including running the codemod), I've had this issue. I've tried the following in my babel.config.js (after adding the metro-react-native-babel-preset package, which I didn't have):

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['react-native-reanimated/plugin'],
}

Despite this, I still get the ReferenceError: Can't find variable: React error. Hopefully there's something I'm missing but I'm relatively new to this and it's already been a little confusing since ejecting from Expo a while ago.

Update: I was missing the [] around the individual preset. Adding that made it work so thanks again.

@klandell
Copy link

Thanks @moonlight8978. Your suggestion of adding useTransformReactJSXExperimental: true to the metro preset configs worked like a charm.

@moonlight8978
Copy link

module.exports = function (api) {
 api.cache(true)

 const presets = ['babel-preset-expo']
 const plugins = ['react-native-reanimated/plugin']

 return {
   presets,
   plugins,
}

@darrylyoung I'm not familiar with expo, but I tried to take a look at babel-preset-expo.
It seems like there is no way that I can pass useTransformReactJSXExperimental option to metro-react-native-babel-preset.
https://github.com/expo/expo/blob/d9ce4c1eceaeaadebb578764d53fcec76fa51b11/packages/babel-preset-expo/index.js#L32-L48

I believe that the only way for using React 17 new JSX transformation with expo is remove babel-preset-expo and add other plugins/presets manually.

@darrylyoung
Copy link

Hi, @moonlight8978. 👋

I believe that the only way for using React 17 new JSX transformation with expo is remove babel-preset-expo and add other plugins/presets manually.

Thanks for the message. I checked babel-preset-expo and it looks like it extends metro-react-native-babel-preset but adds a couple of Expo-specific features. Despite having ejected to the bare workflow, I'm still using @expo/vector-icons. The problem, I think, is that it's pinning an old version of metro-react-native-babel-preset but Expo SDK 41 is due out at the end of the month so hopefully they'll update it.

Regardless, I tried removing babel-preset-expo and had trouble with loading icon fonts (they mention here how the preset handles that). What I ended up doing is this:

module.exports = {
  presets: [
    ['babel-preset-expo'],
    ['module:metro-react-native-babel-preset', { useTransformReactJSXExperimental: true }],
  ],
  plugins: [
    ['react-native-reanimated/plugin'],
    [
      '@babel/plugin-transform-react-jsx',
      {
        runtime: 'automatic',
      },
    ],
  ],
}

I don't have that much experience with Babel so I'm not sure how acceptable this is but I can say that by doing this, I no longer get the Can't find variable: React error and I have no problems with the icon fonts, etc. Maybe, once babel-preset-expo is updated to support the New JSX Transform, I can remove one of the two. Thanks again for your message.

@AleksandrChernyavenko
Copy link

Solution from #646 (comment) is working on development for me, but when I make production build it doesn't work with error "Can't find variable: React"

@jmfigueroa
Copy link

Hello, I updated my babel.config.js using the prescribed method in #646 (comment) but I'm getting the following error:

error: index.js: [BABEL] /Users/jmf/LIVAFORTIS/<AppDirName>/index.js: Unknown option: .useTransformReactJSXExperimental. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options.
- Maybe you meant to use
"preset": [
  ["module:metro-react-native-babel-preset", {
  "useTransformReactJSXExperimental": true
}]
]
To be a valid preset, its name and options should be wrapped in a pair of brackets

Here's my babel.config.js for reference:

module.exports = {
  presets: [
    'module:metro-react-native-babel-preset',
    {
      'useTransformReactJSXExperimental': true,
    },
  ],
  plugins: [
    'babel-plugin-styled-components',
    [
      'module:react-native-dotenv',
      {
        moduleName: '@env',
        path: '.env',
        blacklist: null,
        whitelist: null,
        safe: true,
        allowUndefined: true,
      },
    ],
    [
      require.resolve('babel-plugin-module-resolver'),
      {
        root: ['.'],
        alias: {
          assets: './src/common/assets',
          components: './src/common/components',
          localization: './src/common/localization',
          navigation: './src/navigation',
          screens: './src/screens',
          utils: './src/utils',
        },
      },
    ],
    [
      '@babel/plugin-transform-react-jsx',
      {
        runtime: 'automatic',
      },
    ],
  ],
  env: {
    production: {},
  },
}

I tried:

  • editing the file in a basic text editor
  • adding babel.config.js to my .eslintignore and .prettierignore
  • resetting transform cache
  • deleting node_modules, yarn.lock, Podfile.lock, Pods/ and reinstalling
  • completely deleting/reinstalling app from simulator (npx react-native run-ios)
  • updating "metro-react-native-babel-preset": "^0.66.0" (previously 0.64.0)

Any help would be appreciated!

@moonlight8978
Copy link

moonlight8978 commented Jun 18, 2021

@jmfigueroa Your presets is in wrong format. If you want to pass options to a preset, you have to use the array syntax with:

  • the first element is the name of the preset
  • the second element is the options
presets: [
  [
    'module:metro-react-native-babel-preset',
    {
      'useTransformReactJSXExperimental': true,
    }
  ]
]

not

presets: [
  'module:metro-react-native-babel-preset',
  {
    'useTransformReactJSXExperimental': true,
  },
]

it makes babel think that you are using 2 presets

  • module:metro-react-native-babel-preset
  • and another one is { 'useTransformReactJSXExperimental': true }

@bradfloodx
Copy link

Don't forget to run yarn start --reset-cache after making changes to babel.config.js

@RenaudAubert
Copy link

Hello, I followed this comment and c&p the given babel.config.js into my project but I'm still getting the ReferenceError: Can't find variable: React error. Do I need to reload babel or something? I already tried to clear npm cache without success. Here's my config :

// babel.config.js
module.exports = {
    presets: [
        [
            "module:metro-react-native-babel-preset",
            { useTransformReactJSXExperimental: true },
        ],
    ],
    plugins: [
        [
            "@babel/plugin-transform-react-jsx",
            {
                runtime: "automatic",
            },
        ],
    ],
};

I tried having the @babel/plugin-transform-react-js dependency directly into my package.json but it didn't work.
When creating my react-native project with npx react-native init I directly updated @babel/core and @babel/runtime to their latest version. Maybe it has introcude a conflict? I would greatly appreciate some help because it seems to be working just fine for lots of people I don't understand what I did wrong

@hk-skit
Copy link

hk-skit commented May 17, 2022

I am using react-native with typescript. I am still facing this issue. Here's my babel.config.js:

module.exports = {
  presets: [
    [
      'module:metro-react-native-babel-preset',
      { useTransformReactJSXExperimental: true },
    ],
  ],
  plugins: [
    [
      '@babel/plugin-transform-react-jsx',
      {
        runtime: 'automatic',
      },
    ],
    [
      'module-resolver',
      {
        root: ['./'],
        extensions: ['.ts', '.tsx', '.android.tsx', '.ios.tsx'],
        alias: {
          '~src/*': './src/*',
        },
      },
    ],
  ],
};

I also tried installing @babel/plugin-transform-react-jsx and changed jsx to react-jsx in tsconfig.json but it didn't help. I would appreciate any help on this.

@Dashue
Copy link

Dashue commented May 19, 2022

yarn start --reset-cache solved my issues with typescript

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants