babel / babel/babel

Problem with "this" in React component using JSX

Open
#11,806 1 comment 0 reactions 0 assignees View on GitHub
area: jsx Spec: Classes
Dominant language
TypeScript
Stars
44k
Forks
6k
Avg merge
5d 15h
Merged PRs (30d)
23

Description

## Bug Report

I (and others) get an error when running the build of a create-react-app project ("Minified React error #130 - 'this' in JSX arrow function", see

*Note: I had hoped to find a existing bug, so I [posted the problem as a discussion](https://github.com/babel/babel/discussions/11785) first*

**Current behavior**

With the following code

```jsx
class ComponentWithJsx extends React.Component {
First = () => ; // <- problem

Second = () =>

SUCCESS (ComponentWithJsx)
;

render() {
return ;
}
}
```

I get this error:

> Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
> in Unknown (created by ComponentWithJsx)
> in ComponentWithJsx

I built a minimal, reproducible example by ejecting create-react-app and reducing it to the minimal code which triggers the behavior:

Based on this, @JLHwung created an [REPL](https://babeljs.io/en/repl#?browsers=defaults&build=&builtIns=false&spec=false&loose=false&code_lz=JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AoctAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHr3gBvSnDgAjKHAC8cAEQrNFcoqL8kqjQAoAlOoB8cefsVwiMAK5QecU_YdwAPDAAWwHQiKnAA9FZecOYUigC-FHGUnJCwcHxImCjO1PAsYKRAA&debug=false&forceAllTransforms=false&shippedProposals=true&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=false&presets=env%2Creact%2Cenv&prettier=false&targets=&version=7.10.4&externalPlugins=) (thank you!)

More info in the `README.md` in the [repro](https://github.com/sbusch/create-react-app-8738-repro) and in my comment to the original issue here:

The problem is ultimately caused by the Babel plugin `@babel/plugin-transform-classes`, but it's only happening in conjunction with `@babel/plugin-transform-react-jsx` and `@babel/plugin-proposal-class-properties`.

Tested with newest versions of `@babel/core` and mentioned packages (see [`package.json` in the repro](https://github.com/sbusch/create-react-app-8738-repro/blob/master/package.json))

*Note: I can work around the problem by disabling `@babel/plugin-transform-classes` or by settting the `@babel/plugin-transform-classes` option `{ loose: true}` (or - in a create-react-app project - by limiting the `browserslist` for `@babel/preset-env` to browsers which don't need the `@babel/plugin-transform-classes` transform. For the default `browserslist`, this can be achieved by adding `not ie 11`)*

**Input Code**

From @JLHwung [REPL](https://babeljs.io/en/repl#?browsers=defaults&build=&builtIns=false&spec=false&loose=false&code_lz=JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AoctAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHr3gBvSnDgAjKHAC8cAEQrNFcoqL8kqjQAoAlOoB8cefsVwiMAK5QecU_YdwAPDAAWwHQiKnAA9FZecOYUigC-FHGUnJCwcHxImCjO1PAsYKRAA&debug=false&forceAllTransforms=false&shippedProposals=true&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=false&presets=env%2Creact%2Cenv&prettier=false&targets=&version=7.10.4&externalPlugins=):

```jsx
import React from 'react';

class App extends React.Component {

br = "br";

render = () => {

return (

);
};
}

export default App;
```

**Expected behavior**

No runtime errors should occur. Currently, the value for `this` is somehow lost.

When building and serving the [repro](https://github.com/sbusch/create-react-app-8738-repro), I expect rendering of

> SUCCESS (ComponentWithoutJsx) and
> SUCCESS (ComponentWithJsx)

(as outline in thw README.md there)

**Babel Configuration**

Excerpt from `webpack.config.js` (full file here: ):

```js
{
test: /\.(js|jsx)$/,
include: srcPath,
loader: require.resolve("babel-loader"),
options: {
plugins: [
//*
[
"@babel/plugin-transform-react-jsx",
{
// Rule out that PURE markers are the culprit
pure: false,
},
],
//*/
//*
[
"@babel/plugin-proposal-class-properties",
{
// Enable loose mode to use assignment instead of defineProperty
// See discussion in https://github.com/facebook/create-react-app/issues/4263
loose: true,
},
],
//*/
//*
[
"@babel/plugin-transform-classes",
{
loose: false,
},
],
//*/
],
},
}
```

**Environment**

```
System:
OS: macOS 10.15.5
Binaries:
Node: 14.5.0 - /usr/local/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.5 - /usr/local/bin/npm
npmPackages:
@babel/core: 7.10.4 => 7.10.4
@babel/plugin-proposal-class-properties: ^7.10.4 => 7.10.4
@babel/plugin-transform-classes: 7.10.4 => 7.10.4
@babel/plugin-transform-react-jsx: 7.10.4 => 7.10.4
babel-loader: 8.1.0 => 8.1.0
webpack: 4.43.0 => 4.43.0
```

- Monorepo: no
- How you are using Babel: `loader`

---

Thanks to all contributors for creating Babel!

Contributor guide

Open the contributing guide

Research direction

Start with the README.md and package.json in the linked create-react-app-8738-repro, then run its build with the webpack.config.js plugin combinations described here. Compare the output and runtime behavior with and without the class, JSX, and class-properties transforms. Done means the served reproduction renders both SUCCESS messages without a React runtime error.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react, webpack
Domain
compilers, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.