Next.js: Next.js should not automatically expose the `React` global

Created on 30 Jun 2020  路  6Comments  路  Source: vercel/next.js

Bug report

Describe the bug

When you use JSX in your app, we automatically expose the React global. This allows things like React.useState to work even though it's not imported.

To Reproduce

Use React.useState in your app without an import, and see it work.

Expected behavior

It should not work, and instead, require React be imported.

good first issue bug

Most helpful comment

would adding the 'babel-plugin-react-require' plugin solve this issue?

It would not

Would this mean that pages now should import React as well? What is the rational behind this? I am just curious.

Only when React is used it should be imported. Using JSX is fine without importing:

export default function Page() { return <h1>Hello</h1> }

When doing a useState however it's non-standard that this currently works:

export default function Page() {
  // This should not be possible as it needs React to function
  const [state, setState] = React.useState(false) 
  return <button onClick={() => setState(true)}>{state ? 'State set' : 'set the state'}</button>
}

It should be written as:

import React from 'react'

export default function Page() {
  const [state, setState] = React.useState(false) 
  return <button onClick={() => setState(true)}>{state ? 'State set' : 'set the state'}</button>
}

All 6 comments

would adding the 'babel-plugin-react-require' plugin solve this issue?

Would this mean that pages now should import React as well? What is the rational behind this? I am just curious.

would adding the 'babel-plugin-react-require' plugin solve this issue?

It would not

Would this mean that pages now should import React as well? What is the rational behind this? I am just curious.

Only when React is used it should be imported. Using JSX is fine without importing:

export default function Page() { return <h1>Hello</h1> }

When doing a useState however it's non-standard that this currently works:

export default function Page() {
  // This should not be possible as it needs React to function
  const [state, setState] = React.useState(false) 
  return <button onClick={() => setState(true)}>{state ? 'State set' : 'set the state'}</button>
}

It should be written as:

import React from 'react'

export default function Page() {
  const [state, setState] = React.useState(false) 
  return <button onClick={() => setState(true)}>{state ? 'State set' : 'set the state'}</button>
}

Thanks for the explanation @timneutkens! I saw this a while back: https://twitter.com/sebmarkbage/status/1250284377138802689

What's the take for Next.js here? Should we use
import * as React from "react" or import React from "react? Does it matter?

Next.js automatically injects the proper React import, but when you do need to write it manually, it should be:

import * as React from "react"

Considering this fixed when you upgrade to React 17.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timneutkens picture timneutkens  路  3Comments

olifante picture olifante  路  3Comments

wagerfield picture wagerfield  路  3Comments

jesselee34 picture jesselee34  路  3Comments

sospedra picture sospedra  路  3Comments