react icon indicating copy to clipboard operation
react copied to clipboard

[React 19] Using spread with binary conditional in JSX causes error in dev env for case of using legacy JSX transform

Open undeletable opened this issue 1 year ago • 4 comments

Summary

Prerequisites

  • React app which compiles with legacy JSX transform
  • Add a JSX element with spread operator with binary conditional, e.g.:
      <button
        {...(isCountButtonActive && {
          onClick: () => setCount(currentCount => currentCount + 1)
        })}
      >
        Increment count
      </button>
  • Run app in dev mode

Result

Error is thrown when conditional is evaluated to false:

Uncaught TypeError: Cannot use 'in' operator to search for '__self' in false
    at exports.createElement (chunk-Y64RAOT6.js?v=f4a3421f:775:86)
    at App (App.jsx:3:13)
    at callComponentInDEV (react-dom_client.js?v=f4a3421f:785:18)
    at renderWithHooks (react-dom_client.js?v=f4a3421f:3510:24)
    at updateFunctionComponent (react-dom_client.js?v=f4a3421f:4521:21)
    at beginWork (react-dom_client.js?v=f4a3421f:5096:20)
    at runWithFiberInDEV (react-dom_client.js?v=f4a3421f:864:18)
    at performUnitOfWork (react-dom_client.js?v=f4a3421f:7688:83)
    at workLoopSync (react-dom_client.js?v=f4a3421f:7580:43)
    at renderRootSync (react-dom_client.js?v=f4a3421f:7561:13)

Code fragment where it's thrown:

        if (null != config) for (propName in didWarnAboutOldJSXRuntime || !("__self" in config) || "key" in config || (didWarnAboutOldJSXRuntime = true, warn("Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform")), hasValidRef(config), hasValidKey(config) && (checkKeyStringCoercion(config.key), typeString = "" + config.key), config) hasOwnProperty.call(config, propName) && "key" !== propName && "__self" !== propName && "__source" !== propName && (i[propName] = config[propName]);

Reproduction

https://github.com/undeletable/jsx-spread-with-react-19-rc Click 'Toggle count button state' to reproduce

undeletable avatar Jun 14 '24 22:06 undeletable

I think the "modern" way to do is to conditionally assign the event handler directly within the onClick, like for example:

<button
  onClick={isCountButtonActive ? () => setCount(currentCount => currentCount + 1) : undefined}
>
  Increment count
</button>

saul-atomrigs avatar Jun 16 '24 14:06 saul-atomrigs

@saul-atomrigs Thanks. I know several ways to work that around, including your approach. But the code in my example should work too, as it's valid and spread operator usage too, and not less 'modern' one for sure. That's why I've raised the issue.

undeletable avatar Jun 16 '24 15:06 undeletable

I'm going to work on the fix

undeletable avatar Jun 17 '24 20:06 undeletable

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Sep 15 '24 21:09 github-actions[bot]

Still an issue. Upgraded to the latest RC in repository with reproduce.

undeletable avatar Sep 16 '24 09:09 undeletable

There's PR with fix: https://github.com/facebook/react/pull/29925 Updated it with the latest changes from main branch

undeletable avatar Sep 16 '24 09:09 undeletable

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Dec 15 '24 11:12 github-actions[bot]

Still an issue in 19.0.0

undeletable avatar Dec 15 '24 13:12 undeletable

bump

chidev avatar Jan 09 '25 20:01 chidev

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Jun 09 '25 22:06 github-actions[bot]

Still an issue with React 19.1.0

undeletable avatar Jun 10 '25 15:06 undeletable

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

github-actions[bot] avatar Sep 08 '25 17:09 github-actions[bot]

Still an issue with React 19.1.1

undeletable avatar Sep 08 '25 19:09 undeletable

Is there any progress with it? The code is full of this syntax, and without this fix I cannot upgrade to v19.

nirapx avatar Oct 27 '25 08:10 nirapx

@nirapx I've got PR https://github.com/facebook/react/pull/29925 fixing this, but still it's awaiting review

undeletable avatar Oct 27 '25 10:10 undeletable