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.
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
bvaughn
mentioned this pull request
|
@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

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.










Summary
Displays the
refof 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
keyin the view too so we could create a "Misc" view.On the other hand, the
refwill eventually be just another prop (if I understood reactjs/rfcs#107 correctly) so it'll merge with the props view eventually.Test Plan