mobx: DisplayName not being forwarded when wrapped in
When I receive a printed call stack from React, the components wrapped in observer show up as observerComponent
at observerComponent (http://localhost:3000/static/js/bundle.js:119423:69)
at div
at observerComponent (http://localhost:3000/static/js/bundle.js:119423:69)
at PrimaryWindow (http://localhost:3000/static/js/bundle.js:4346:5)
and in the callstack in the debugger shows up as anonymous
<anonymous> (/Users/johntwigg/development/crypto/loopNFT/ui/src/components/Cinema/CinemaMain.tsx:35)
<anonymous> (/Users/johntwigg/development/crypto/loopNFT/ui/node_modules/mobx-react-lite/src/observer.ts:104)
<anonymous> (/Users/johntwigg/development/crypto/loopNFT/ui/node_modules/mobx-react-lite/src/useObserver.ts:115)
Intended outcome:
Ideally, the underlying React Name would be maintained. CinemaMain in this case.
Actual outcome:
anonymous and observerComponent
Looking at issue #3422 doesn’t seem to resolve or change the behavior for me. For example
const FocusLane : React.FC = observer(() => {...})
FocusLane.displayName = "FocusLane"
has no impact.
Any ideas? I’m open to workarounds.
Versions
➜ ui git:(mobx) ✗ npm list --depth 2 | grep mobx
├─┬ mobx-react-lite@3.4.0
│ ├── mobx@6.6.1
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 17 (3 by maintainers)
I just spent a good couple of hours debugging this problem, and here’s what I’ve found.
The biggest issue is that React doesn’t respect the
displayNameproperty any more, which appears to be an intentional change as part of what they call Native Component Stacks, in which they use an actual stack trace to generate their stacks. IMHO, this is a mistake as it makes debugging with higher order components likeobserververy difficult. I have weighed in on the relevant issue here: https://github.com/facebook/react/issues/22315 (don’t let the name fool you, it happens in every browser).To work around this, as suggested above, you can instead redefine
nameinstead ofdisplayName. Note this must be done viaObject.definePropertyand not a vanilla assignment. Unfortunately, this doesn’t work in Firefox, because Firefox stacks ignorename, and that’s where React is getting its info from. Still, as I will grudgingly admit to Chrome’s overwhelming popularity, that might be a workaround for now.On top of all this, if you’re using the “set the display name after defining the component” strategy (option 2 on what I consider the definite source on this, https://github.com/mobxjs/mobx/issues/141#issuecomment-470883978), this still doesn’t work. The reason for this is that you’re changing the
displayName(or if working around, thename) of thememowhich wraps the actual component, and React, through some black magic, unwraps the actual component when computing the stack trace, so the name is still missing.To work around this, I had to author the following dubious code:
Would it be possible to define
displayNameon thememoas a bidirectional computed property (set and get) which would just proxy the underlyingwrappedComponent’s displayName? I haven’t investigate this yet but maybe it would be possible.