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

Warn if outdated JSX transform is detected #28781

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ describe('ReactDeprecationWarnings', () => {
);
});

// Disabling this until #28732 lands so we can assert on the warning message.
// (It's already disabled in all but the Meta builds, anyway. Nbd.)
// @gate TODO || !__DEV__
// @gate !disableStringRefs
it('should warn when owner and self are the same for string refs', async () => {
class RefComponent extends React.Component {
Expand All @@ -114,8 +117,11 @@ describe('ReactDeprecationWarnings', () => {
await waitForAll([]);
});

// Disabling this until #28732 lands so we can assert on the warning message.
// (It's already disabled in all but the Meta builds, anyway. Nbd.)
// @gate TODO || !__DEV__
// @gate !disableStringRefs
it('should warn when owner and self are different for string refs', async () => {
it('should warn when owner and self are different for string refs (createElement)', async () => {
class RefComponent extends React.Component {
render() {
return null;
Expand Down Expand Up @@ -143,7 +149,7 @@ describe('ReactDeprecationWarnings', () => {

// @gate __DEV__
// @gate !disableStringRefs
it('should warn when owner and self are different for string refs', async () => {
it('should warn when owner and self are different for string refs (jsx)', async () => {
class RefComponent extends React.Component {
render() {
return null;
Expand Down
27 changes: 27 additions & 0 deletions packages/react/src/__tests__/ReactCreateElement-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,4 +466,31 @@ describe('ReactCreateElement', () => {
});
expect(test.props.value).toBeNaN();
});

it('warns if outdated JSX transform is detected', async () => {
// Warns if __self is detected, because that's only passed by a compiler
expect(() => {
React.createElement('div', {className: 'foo', __self: this});
}).toWarnDev(
'Your app (or one of its dependencies) is using an outdated ' +
'JSX transform.',
{
withoutStack: true,
},
);

// Only warns the first time. Subsequent elements don't warn.
React.createElement('div', {className: 'foo', __self: this});
});

it('do not warn about outdated JSX transform if `key` is present', () => {
// When a static "key" prop is defined _after_ a spread, the modern JSX
// transform outputs `createElement` instead of `jsx`. (This is because with
// `jsx`, a spread key always takes precedence over a static key, regardless
// of the order, whereas `createElement` respects the order.)
//
// To avoid a false positive warning, we skip the warning whenever a `key`
// prop is present.
React.createElement('div', {key: 'foo', __self: this});
});
});
23 changes: 23 additions & 0 deletions packages/react/src/jsx/ReactJSXElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ let specialPropKeyWarningShown;
let specialPropRefWarningShown;
let didWarnAboutStringRefs;
let didWarnAboutElementRef;
let didWarnAboutOldJSXRuntime;

if (__DEV__) {
didWarnAboutStringRefs = {};
Expand Down Expand Up @@ -722,6 +723,28 @@ export function createElement(type, config, children) {
let ref = null;

if (config != null) {
if (__DEV__) {
if (
!didWarnAboutOldJSXRuntime &&
'__self' in config &&
// Do not assume this is the result of an oudated JSX transform if key
// is present, because the modern JSX transform sometimes outputs
// createElement to preserve precedence between a static key and a
// spread key. To avoid false positive warnings, we never warn if
// there's a key.
!('key' in config)
) {
didWarnAboutOldJSXRuntime = true;
console.warn(
'Your app (or one of its dependencies) is using an outdated JSX ' +
'transform. Update to the modern JSX transform for ' +
'faster performance: ' +
// TODO: Create a short link for this
'https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html',
);
}
}

if (hasValidRef(config)) {
if (!enableRefAsProp) {
ref = config.ref;
Expand Down