caplin / FlexLayout

Docking Layout Manager for React
MIT License
919 stars 173 forks source link

Uncaught TypeError: Cannot read properties of null (reading 'getBoundingClientRect') #352

Closed jugglingcats closed 10 months ago

jugglingcats commented 1 year ago

EDIT: see comment for more detailed info and reproduction.

Describe the bug

Apologies in advance but this is an intermittent issue which only occurs in a specific context and I haven't managed to create a concise reproduction of it.

We are using flexlayout in a package we are shipping @glowbuzzer/controls. We have built example apps using this package and all works fine.

We also include it in our documentation site. In the documentation site, the setup is a little more complex. We use MDX and author code blocks which are transformed automatically by a Vite plugin we've written, so the reader can see the code and the resulting render.

In the documentation site, occasionally, on one or our more complex demos, the page fails to load with the error below:

Uncaught TypeError: Cannot read properties of null (reading 'getBoundingClientRect')
    at Layout.getDomRect (Layout.tsx:412:38)
    at updateRect (TabButton.tsx:105:35)
    at TabButton.tsx:97:9

This is the page that fails: https://www.glowbuzzer.com/docs/gbr/tiles/ThreeDimensionalSceneTile.

The frequency of the failure seems to be related to network connection speed - slower connections seem to give the error more often.

I'm hoping you can shed some light on this issue...

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

Turn off caching in devtools and keep refreshing the page: https://www.glowbuzzer.com/docs/gbr/tiles/ThreeDimensionalSceneTile

Expected behavior

It should work consistently.

Operating System

Windows

Browser Type?

Chrome

Browser Version

105

Screenshots or Videos

image

Additional context

No response

jugglingcats commented 1 year ago

With a bit of work I've managed to boil this down to a short repro. See https://github.com/jugglingcats/flexlayout-352.

It seems to be an interaction between flexlayout-react, React.Suspense and @react-three/fiber (which uses suspend-react under the covers).

There is a simple workaround which is to add another, nested Suspense wrapper within the tab component render. I suspect it is something to do with the fact that @react-three/fiber has it's own renderer.

I honestly don't know if this is a bug in flexlayout-react or somewhere else, but the error comes from flexlayout-react code, and things seem to work fine if flexlayout-react is removed from the flow.

paralin commented 10 months ago

I'm getting the same thing. The bug is in the FlexLayout code IMO.

this.selfRef.current becomes null when the component is being unmounted from the page.

https://github.com/caplin/FlexLayout/blob/master/src/view/Layout.tsx#L415

The code uses the ! operator to override TypeScript's warning that current may be null. These getters should instead use ? to check if "current" is null before calling getBoundingClientRect.