16

We are using React and TypeScript in our current project and I come across below behavior.

import React, { Component } from 'react';

I replace the above line with the one below since it seems to be using Component import only.

import { Component } from 'react';

And I was thrown below error

Error: 'React' refers to a UMD global but the current file is a module. Consider adding an import instead.

I tried looking it up on Stack and GitHub, found few articles and discussion but still unclear about why it's happening.

Would be more interested in whether React or Typescript is throwing it and WHY ? Not the ways to fix it.

Also some light around UMD, why it's used here ?

Jaspreet Singh
  • 1,672
  • 1
  • 14
  • 21
  • Does this answer your question? ['React' refers to a UMD global, but the current file is a module](https://stackoverflow.com/questions/64656055/react-refers-to-a-umd-global-but-the-current-file-is-a-module) – Liam Jun 21 '22 at 19:52

3 Answers3

18

Are you rendering any jsx in the file? If so, you do need to import React, since those jsx tags compile into calls to React.createElement(). Without the import, the references to React are trying to reference a global variable, which then results in that error.

If you're using eslint, i'd recommend using eslint-plugin-react and turning on the rule react-in-jsx-scope, which will catch this case.

Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • could you please answer my comment in other answer ? – Jaspreet Singh Feb 19 '19 at 16:34
  • 1
    If you're not using JSX, then you don't need to import React. Each file that uses JSX needs its own import of React. Transpiling JSX is done at build time, not runtime; the virtual DOM isn't created until runtime. – Nicholas Tower Feb 19 '19 at 17:37
  • 6
    Since React 17 the `React` import is no longer required for JSX files. – vhs Mar 24 '21 at 06:52
5

The way JSX syntax is transpiled depends on compiler options, jsxFactory option defaults to React.createComponent. This means that <p/> is transpiled to React.createComponent('p'), and React is expected to exist in the scope of a module.

If there's no React import, it's expected that React global should exist.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • that means if I'm not using `tsx` inside my `render` method, it will run fine ? Also, if IMO react creates a full virtual dom object before transpiling JSX to actual DOM, that means one react import at super parent level should be fine ? Could you also attach some links for reference which can be helpful in understanding this transpiling process better. – Jaspreet Singh Feb 19 '19 at 16:30
  • I linked to the manual. It's not related to virtual DOM or how React works. If you use JSX syntax in a module, you can be sure that React.createElement will be used, so React is needed to be imported, If you don't use JSX, you may not need it to be imported. As a rule of thumb, it should be imported in .tsx files to avoid this error. – Estus Flask Feb 19 '19 at 16:33
  • Thanks, I will go through the links and get back to you if needed. Would like to keep it unanswered for some time so that other's can also give their inputs. – Jaspreet Singh Feb 19 '19 at 16:37
1

With the introduction of a new JSX transform in React 17, it is no longer necessary to import React in every file that uses JSX. Simply edit the jsx compiler option in your tsconfig to use "react-jsx".

{
    "compilerOptions": {
        "jsx": "react-jsx"
    }
}

The old default transformation ("jsx": "react"), compiled JSX into calls to React.createElement, so React had to be in scope for it to work. The react-jsx transform, however, uses the _jsx function and automatically inserts the import for it.

After this change, unused imports of React can be safely removed. After upgrading to the newer JSX transform, you may run the following command in the root of your project to remove such useless imports.

npx react-codemod update-react-imports
Unmitigated
  • 76,500
  • 11
  • 62
  • 80