Repository navigation
fix(hooks): warn and no-op when a property setter is called after dispose - #316
Merged
Merged
Conversation
mfazekas
enabled auto-merge (squash)
July 6, 2026 11:45
A setter returned by useRiveNumber/useRiveString/etc. can be captured in a stale closure (async callback, timeout) and fire after its property was disposed by a deps change or unmount. The write then hits the disposed hybrid and throws "Cannot set hybrid property ... NativeState is null" - fatal when uncaught in release. Route writes through the liveRef that useDisposableMemo already maintains (nulled at dispose time), the same guard useRiveTrigger uses, so stale writes become safe no-ops. Adds jest regression tests plus an on-device harness test that fails on the unguarded hook.
Mirror useRiveTrigger: instead of silently ignoring a setter call on a missing property, warn with the path and the likely cause (stale closure after unmount vs. instance still loading) so misuse stays visible without crashing. Also reformat with prettier 3.8.3 (the version main resolves; CI lint failed on formatting produced by 3.6.2).
mfazekas
force-pushed
the
fix/stale-setter-write
branch
from
July 6, 2026 12:11
cc01bda to
24737dc
Compare
mfazekas
pushed a commit
that referenced
this pull request
Jul 6, 2026
🤖 I have created a release *beep* *boop* --- ## [0.4.14](v0.4.13...v0.4.14) (2026-07-06) ### Bug Fixes * **android:** bump rive-android to 11.6.2 ([#317](#317)) ([ae66b24](ae66b24)) * **android:** don't re-acquire a disposed Rive file on view re-attach ([#319](#319)) ([4259723](4259723)) * **hooks:** no-op stale property setter calls after dispose ([#316](#316)) ([dbb4dd7](dbb4dd7)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
mfazekas
added a commit
that referenced
this pull request
Jul 7, 2026
Merges `main` up to the 0.4.14 release into the iOS experimental branch. No conflicts. Notable changes pulled in: 1. fix(android): don't re-acquire a disposed Rive file on view re-attach (#319) 2. fix(hooks): no-op stale property setter calls after dispose (#316) 3. fix(android): bump rive-android to 11.6.2 (#317) — resolves to 11.6.2 here (up from 11.6.1) On the #319 native fix: this branch has the legacy/new Android backend split, so git's rename detection applied the fix to the `android/src/legacy` variant of `RiveReactNativeView.kt` — which is correct, since the crash is a property of upstream `RiveAnimationView`'s cached `rendererAttributes.resource`. The `android/src/new` backend is a separate `TextureView`/`CommandQueue` implementation with no such code path, so the same tweak neither applies nor is needed there. A re-attach lifecycle bug in the new backend, if any, would be a separate fix. --------- Co-authored-by: Rive Engineering <60802183+rive-engineering@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
A setter returned by
useRiveNumber/useRiveString/etc. can be captured in a stale closure (async callback, timeout) and fire after its property was disposed by a deps change or unmount. The write then reaches the disposed hybrid and throwsCannot set hybrid property ... NativeState is null— fatal when uncaught in a release app.The fix routes writes through the
liveRefthatuseDisposableMemoalready maintains (nulled at dispose time) — the same guarduseRiveTriggeruses. A write after unmount warns and no-ops (with the path and likely cause) instead of throwing; a write captured before a deps change targets the hook's current property, matchinguseRiveTriggersemantics.propertystays in theuseCallbackdeps so the setter identity still changes with the property.Tests: jest cases for the after-unmount no-op+warn and the deps-change redirect, plus an on-device harness test (
staleSetterWrite.test.tsx) that fails on the unguarded hook — verified on the Android emulator on both backends.