Skip to content

fix: shadow properties on dispose to prevent React DEV crash#1298

Draft
mfazekas wants to merge 1 commit intomrousavy:mainfrom
mfazekas:fix/dispose-shadow-properties
Draft

fix: shadow properties on dispose to prevent React DEV crash#1298
mfazekas wants to merge 1 commit intomrousavy:mainfrom
mfazekas:fix/dispose-shadow-properties

Conversation

@mfazekas
Copy link
Copy Markdown
Contributor

@mfazekas mfazekas commented Apr 22, 2026

Before nulling NativeState in dispose(), shadow all enumerable prototype properties with non-enumerable own properties and define `__disposed = true`. This prevents React DEV tooling (`for...in` iteration in `addObjectDiffToProperties` and `deepFreezeAndThrowOnMutationInDev`) from accessing getters on a disposed object, which would throw and crash Fabric's scheduler.

On frozen objects the shadowing fails silently, which is consistent — `setNativeState(nullptr)` also fails on frozen objects, so NativeState stays valid and property access remains safe.

Fixes #1296

Library-level workaround: Libraries can work around this without waiting for this fix by shadowing properties from JS before calling `dispose()`. See rive-app/rive-nitro-react-native#227 for an example `callDispose()` helper.

When a HybridObject used as a view prop is disposed, React's DEV-mode
profiling (logComponentRender/addObjectDiffToProperties) iterates the
object's properties via for...in, accessing getters that throw because
NativeState was nulled. The throw during commitPassiveMountEffects
corrupts Fabric's scheduler, freezing the app.

Before nulling NativeState, shadow all enumerable prototype properties
with non-enumerable own properties so for...in skips them. Also define
__disposed=true for debugger visibility.

On frozen objects (from deepFreezeAndThrowOnMutationInDev), shadowing
fails but setNativeState(nullptr) also fails, so property access
remains safe.

Fixes mrousavy#1296, mitigates mrousavy#1083
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 22, 2026

@mfazekas is attempting to deploy a commit to the Margelo Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dispose() on HybridObject prop crashes Fabric scheduler in DEV mode

1 participant