Change:
Provided is a code sandbox with a very simplified version of the code which triggered this bug. the code sandbox app in a new window developer tools the "Components" tab on the "App" component Observe that devtools crashed, and the console prints out an error similar to this: This happens in both Firefox and Chrome. Every time react-devtools-extensions 13.5- Could not inspect element with id 2 No response
I see a slightly different error than the one reported: I can repro this though so that's good. I can fix this.
Fix will go out with the next release.
Not sure what your release cycle is, but I'm using the extension built from source in the meantime. Works fine now, thanks!
I have a similar issue. I created a PR that should fix the crash: To reproduce: clone into install dependencies run application: open the -Tab in click on the component you should see following error: !
I would appreciate if you could make a reduced repro that didn't import other frameworks (like this i18n framework). Seems like the core of this problem is related, but I'm having to dig through unfamiliar (TypeScript) code trying to narrow down why it's still throwing in .
thanks for your help! I simplified the example a bit and marked the key-part. Just replace the file with following content: jsx import React from 'react' export const getFallbackProxy = (prefixKey?: string): any =new Proxy((prefixKey ? () =prefixKey : {}) as any, { get: (_target, key: string) =getFallbackProxy(prefixKey ? : key), }) export const initI18nReact = () ={ const context = React.createContext({} as any) const Component: React.FunctionComponent<{ initialLocale: string }= (props) ={ const [isLoadingLocale, setIsLoadingLocale] = React.useState<boolean(false) const [currentLocale, setCurrentLocale] = React.useState<string | null(null) const [LL, setLL] = React.useState(getFallbackProxy()) const setLocale = async (newLocale: string): Promise<void={ setIsLoadingLocale(true) setLL( //
// KEY-PART BEGIN --------------------------------------------------------------------- //
new Proxy( {}, { get: (target: any, key: string) ={ (, key) return () =key }, }, ) as any, //
// KEY-PART END --------------------------------------------------------------------- //
) setCurrentLocale(newLocale) setIsLoadingLocale(false) } !currentLocale && !isLoadingLocale && setLocale((props as any).initialLocale 'en') if (!isLoadingLocale && !LL) { return null } const ctx = { setLocale, isLoadingLocale, locale: currentLocale, LL } return <context.Provider value={ctx}{props.children}</context.Provider} return { component: Component, context } } //
const { component: TypesafeI18n, context: I18nContext } = initI18nReact() export { I18nContext } export default TypesafeI18n and then run When you look at the console output you can see all access-attempts to the proxy being logged: ! The uppercased names come from the application-code itself. Then it gets interesting.. React Dev Tools tries to access that proxy with a lot of different keys, the Proxy can not handle (and should not handle). Not so sure where this gets called and I currently don't have a lot time to dig deeper.. I assume this PR is 'fixing' the wrong thing since the problem lays somewhere else.
I'm seeing a different error from the repro you shared above: The error I was seeing on the PR was:
But you see all the accesses to the Proxy from React Dev Tools? Forget the error for now. If we can tell React Dev Tools to not access the Proxy, the error should be gone.
It's not as simple as that. When an element is inspected, DevTools must serialize its props/state/hooks (using ) to send values from the "backend" (running in the page with your app) to the "frontend" (DevTools extension UI). (These are in separate memory spaces, so we can't just share the value directly.) As a side note, it also needs to avoid deeply cloning objects because that can add a lot of overhead and slow things down, so instead it shallowly clones them before serializing. The main utility that does this is here: The code path that's triggering all of the accesses you're pointing out is here: Which calls this function to loop over props: Then eventually this method throws when trying to stringify a property: More specifically, this line: Calling with the proxy value throws. Replacing that method of mapping keys with a that pushes to an array also throws. You can reproduce this error with the following stripped down code: Q: Why can't you just treat this Proxy object differently? A: Because (to my knowledge) there is no way to determine if a value is a . Q: Is there a workaround for this? A: You could make your detectable using the operator, but it would require custom work on your side to support. You could also defined a custom accessor to limit the values that were iterated over. Q: Is there something (hacky) that DevTools could do to detect this case. A: Maybe? Maybe we could check something like to detect an edge case like this, but I'm not sure if this would have other negative consequences. I'm also not sure what we would do with it once we had detected it. Just show a special shallow "[[Proxy]]" string or something? It wouldn't be inspectable.
thanks for your detailed analysis. In my opinion the best solution would be to define the method on the proxy-handler. I tested it with the current React Dev Tools but it seems you don't jet check the available properties with am I right? So work on both ends would be required.
This sounds like a reasonable approach. That's right. I don't think it's generally desirable that we limit the values displayed to being only properties found directly on the object. That being said, maybe we could do something like this as a fallback. However, even after doing something like this, I'm seeing a different runtime error. I would welcome proposals/contributions from you to improve the way DevTools works with edge case objects like the type of Proxy this library uses.
not so sure if detecting a proxy by the content of the error-message is a good solution. the wording could change different browsers may have different wording I recently saw a localized DevTool environment, so maybe also the error-messages are not english Is there another way to check if we access an object? Maybe use something like:
I don't think that approach makes sense. If it's already an array, we wouldn't need to convert it. The purpose of calling is to simplify handling different types of iterables. That being said, I think even if we solve the iteration issue (which the error message check does, even if not in a very robust way) I think we'll still have other issues.
Ah, sorry, I didn't check the context of that array example. This code is here to display a graphical representation of an object somewhere inside the React Dev Tools? I think a better solution would be to change this to and add a new case inside the function that uses (data)
I don't think the above code works, because it would hit false positives for HTML collectins or regular expressions. The only way I know of to check this would be to use the non-standard property (which seems like not a great idea).
in other words: we are not able to find a solution to the problem? So also HTML collections and regular expressions throw an error in the same line as a Proxy? But looking at the function you have already a way to detect these two types. So I don't see why the code mentioned above should not work. It could indeed create false positives, but at least it will not throw an error.
That is correct. They would if you tried to invoke . Look at the surrounding code: We only enter the code path for "iterator" (and "opaque_iterator"). Your proposal, seemingly, was to enter it always and interpret a as a Proxy detection. This would break the other types I mentioned. Alternately, if we left this check in place, then the / would never run for Proxies:
I just created a PR that shows the implementation I would imagine. It has no side-effect on the detection of regular expressions and collections. It just handles cases, where accessing and executing e.g. the property of a proxy throws an error.
I tried an approach very similar and it didn't work for me (in Node) until I removed the check above. That's interesting. can you add a failing test to
yes, just give me a few days to find time for that
Sounds good!

Discussion:
`); }); <ins> // See github.com/facebook/react/issues/21654 it('should support Proxies that dont return an iterator', async () => { const Example = () => null; const proxy = new Proxy( {}, { get: (target, prop, receiver) => { target[prop] = value => {}; return target[prop]; }, }, ); const container = document.createElement('div'); await utils.actAsync(() => ReactDOM.render(<Example proxy={proxy} />, container), ); const inspectedElement = await inspectElementAtIndex(0); expect(inspectedElement.props).toMatchInlineSnapshot(` Object { "proxy": Object { "$$typeof": Dehydrated { "preview_short": ƒ () {}, "preview_long": ƒ () {}, }, "Symbol(Symbol.iterator)": Dehydrated { "preview_short": ƒ () {}, "preview_long": ƒ () {}, }, "constructor": Dehydrated { "preview_short": ƒ () {}, "preview_long": ƒ () {}, }, }, } `); }); </ins> describe('$r', () => { it('should support function components', async () => { const Example = () => {

// but this seems kind of awkward and expensive. return 'array_buffer'; } else if (typeof data[Symbol.iterator] === 'function') { <del> return data[Symbol.iterator]() === data ? 'opaque_iterator' : 'iterator'; </del> <ins> const iterator = data[Symbol.iterator](); if (!iterator) { // Proxies might break assumptoins about iterators. // See github.com/facebook/react/issues/21654 } else { return iterator === data ? 'opaque_iterator' : 'iterator'; } </ins> } else if (data.constructor && data.constructor.name === 'RegExp') { return 'regexp'; } else {