-
Notifications
You must be signed in to change notification settings - Fork 47k
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
devtools: Add ref
to inspect element view
#21879
base: main
Are you sure you want to change the base?
Conversation
if ( | ||
(typeof HTMLElement !== 'undefined' && data instanceof HTMLElement) || | ||
// cross-realm HTMLElement? | ||
/^\[object HTML.+Element\]$/.test(Object.prototype.toString.call(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell this is only needed for the shell at the moment. Without this change
function Example() {
const ref = React.useRef();
return <React.Fragment><div ref={ref} /><SomeComponent foo={ref} /></React.Fragment>
}
would also crash if one would attempt to inspect SomeComponent
since foo.current
would not be considered an HTMLElement
. I can add the described case to the existing shell to make sure we don't regress when removing the special casing of ref
.
I think I dig this change overall. I'm going to poke at the UI a little. May have a nit or two. |
The
Yeah. Makes me wonder if we should just show it inline, within the props panel...but maybe this would be confusing to people, since it's not editable? |
Another idea would be to have it under "Props" but a little bit separate (e.g. with a horizontal divider). Though my initial idea also was to just put them in the props. My concern was not really about editable vs not editable but that
I always miss that, thanks!. |
@@ -131,6 +132,13 @@ export default function InspectedElementView({ | |||
store={store} | |||
/> | |||
|
|||
<InspectedElementRefTree |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do keep ref
as a separate panel, I think it should be above "props" because it's kind of a top-level thing (like key
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just marking this unresolved for visibility.
I always view the order in "what is most important during debugging" and I don't think ref
is more important than other props. Case in point: There hasn't been any request to expose the ref in devtools.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There hasn't been any request to expose the ref in devtools.
That's a good point!
Although at the same time, sometimes people don't know that it's something they could have asked for.
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementRefTree.js
Outdated
Show resolved
Hide resolved
packages/react-devtools-shared/src/devtools/views/Components/InspectedElementRefTree.js
Outdated
Show resolved
Hide resolved
Can you tell me a little more about this case? |
What if I added a new section called "special props" (to match the React docs) and it had "key" and "ref" ? |
@eps1lon How do you feel about an alternative like this? Key may not make the cut here. Despite what the docs say, Sebastian thinks it's more about the parent than the currently-selected element (and I see this point) |
This Twitter vote seems like here's context 🗳 |
I had some trouble making sure that All of these things can be done in code but I'm relying more and more on devtools for analyzing which prop goes where.
That seems fine to me. Though I don't have any strong opinions about either variant (props, special props, with key, without key) etc since I'm comfortable distinguishing their semantics. I think we'll see over time if the UI is confusing or not. |
// Ref is a special case; | ||
// don't dehydrate it in the same way (because it's not hydratable/inspectable). | ||
// Just stringify it instead... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is ref
different than a prop holding a ref? For example, before React.forwardRef
we often had a custom prop like forwardedRef
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good question. Ref is different (at least currently) because it has special React semantics. But you're right, a custom prop name like forwardedRef
would be inspectable and would show Fiber internals. Maybe we need a more robust solution for filtering keys like that on the DevTools side. 🤔 Could be a follow up to consider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also to consider: The ref
might not point to a DOM element but point to imperative methods or other mutable values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My gut feeling was that stringifying is still okay in that case, but maybe...I don't know. I don't really know if I believe in this change overall yet.
I like that. But we need to make sure that no other component with a header can be rendered in between (in the future). |
24370f6
to
04f1176
Compare
@gaearon said: #21796 (comment)
Yes and no. At least |
04f1176
to
bcaf20b
Compare
bcaf20b
to
c39658e
Compare
c39658e
to
474d8a5
Compare
I think most DOM related |
I guess the proxy snapshot just lists every accessed property
474d8a5
to
3fc0c2e
Compare
Summary
Displays the
ref
of an inspected element if the element has one. Was a bit difficult to track a particular ref through a somewhat larger component tree.Ref to a class instance
Ref to an Element
anonymous callback ref
named callback ref
The UI feels a bit lost since we only have a single value in this new section. Ideally we'd have the
key
in the view too so we could create a "Misc" view.On the other hand, the
ref
will eventually be just another prop (if I understood reactjs/rfcs#107 correctly) so it'll merge with the props view eventually.Test Plan