Skip to content

Conversation

@eps1lon
Copy link
Collaborator

@eps1lon eps1lon commented Apr 22, 2025

Summary

Previously Promises were serialized as normal objects. This worked out for used Promises just fine:
CleanShot 2025-04-22 at 21 34 01

However, this only worked because we treated Promises as objects and enumerated all their properties. This triggered some unactionable warnings in Next.js where some props were both Promises and enumeration of those props triggered warnings.

Now we special case any Thenables and properties of their subclasses that React special cases (status, value and reason).

We use the same duck-typing logic for detecting Thenables as React.

How did you test this change?

  • Added cases for all used Promise types and unused Promises

    CleanShot 2025-04-24 at 11 51 21

  • Checked local build against Next.js app to ensure no more warnings are logged
    CleanShot 2025-04-22 at 21 42 24
    Previously:
    CleanShot 2025-04-22 at 21 47 32

@eps1lon eps1lon requested a review from hoxyq April 22, 2025 19:58
@github-actions github-actions bot added the React Core Team Opened by a member of the React Core Team label Apr 22, 2025
case 'fulfilled':
if (showFormattedValue) {
const formatted = formatDataForPreview(data.value, false);
return `fulfilled Thenable {${truncateForDisplay(formatted)}}`;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too much of a fan of fulfilled Thenable {someString}. Open to suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we really want to be accurate about naming, then Thenable is probably the best option, but I would expect it to be Promise in 99.9 % of cases in user land. Both options are okay to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, same concern here. I'll just use the name logic we use for class_instance unless it's a plain object which is the only case where we fallback to "Thenable".

So you'd actually get "Promise" and when you do subclassing and pre-seed the special properties, you'd also get the right name

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

## Development

This target should be run in parallel with the `react-devtools-inline` package. The first step then is to run that target following the instructions in the [`react-devtools-inline` README's local development section](https://github.com/facebook/react/tree/main/packages/react-devtools-inline#local-development).
This target should be run in parallel with the `react-devtools-inline` package. The first step then is to run that target following the instructions in the [`react-devtools-inline` README's local development section](../react-devtools-inline/README.md#local-development).
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case 'null':
case 'undefined':
return data;
return String(data);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not caught by types since other callsites of formatDataForPreview(undefined) always coerced the return value of formatDataForPreview to a string. But the annotated return type of formatDataForPreview is string.

Hardening types by changing data to mixed is annoying since so many lines rely on data being any.

@eps1lon eps1lon force-pushed the sebbie/04-22-_devtools_allow_inspection_of_used_thenables branch from a939050 to b140921 Compare April 22, 2025 20:04
@eps1lon eps1lon force-pushed the sebbie/04-22-_devtools_allow_inspection_of_used_thenables branch from b140921 to a58ff7c Compare April 22, 2025 20:24
case 'fulfilled':
if (showFormattedValue) {
const formatted = formatDataForPreview(data.value, false);
return `fulfilled Thenable {${truncateForDisplay(formatted)}}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we really want to be accurate about naming, then Thenable is probably the best option, but I would expect it to be Promise in 99.9 % of cases in user land. Both options are okay to me.

@hoxyq
Copy link
Contributor

hoxyq commented Apr 23, 2025

Are you using some custom fonts in your browser? I am wondering what are these weird offsets for properties values text on the screenshots.

@eps1lon
Copy link
Collaborator Author

eps1lon commented Apr 24, 2025

Are you using some custom fonts in your browser? I am wondering what are these weird offsets for properties values text on the screenshots.

I have the default size in Chrome at "very large" which most UIs don't account for if they try to align other stuff with text via pixels when fonts are in em/rem (as they should be).

Co-authored-by: Ruslan Lesiutin <rdlesyutin@gmail.com>
@eps1lon eps1lon merged commit 197d6a0 into facebook:main Apr 24, 2025
239 checks passed
@eps1lon eps1lon deleted the sebbie/04-22-_devtools_allow_inspection_of_used_thenables branch September 22, 2025 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants