[core] fix(ResizeSensor): compatibility with React 18 #5362
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #5313 & another bug
Checklist
(If you think this needs tests or docs, I'll update the PR.)
Changes proposed in this pull request:
Firstly, this fixes #5313 by defining an explicit return type for
render()
.The difference between React 18 and 16 here seems to be that React 18 specifies
ReactFragment = Iterable<ReactNode>
, while React 16 specifies{} | ReactNodeArray
. The definition ofonly
drops the array, so the compiled type declaration is an union of what's left ofReactNode
. That breaks when the newer@types/react
doesn't allow{}
. SpecifyingReactNode
should allow the union at compile time, and then the compiledrender(): ReactNode
is compatible with any version of React.A quick grep for
React.Children.only
suggests thatpackages/table/src/common/loadableContent.tsx
andpackages/table/src/interactions/draggable.tsx
are also affected, but I didn't have time to test them right now.Secondly, this makes
ResizeSensor
work with React 18 StrictMode and its "reusable state", which essentially runs effects twice - against their own docs forcomponentWillUnmount
. (The docs make this very enjoyable to debug.)The current code assumes that the component is dumped after
componentWillUnmount
so it doesn't bother to clearthis.element
. This permanently disables the observer sinceobserveElement
will then think the element is already being observed. I addedthis.element = null
to make it "reusable".Reviewers should focus on:
If this breaks something subtle I didn't notice, I guess?