useDisposableMemo disposes native objects in effect cleanup, so a subtree hidden by React <Activity> crashes in release builds when shown again
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- react, react-native, typescript
Hướng nghiên cứu
Start with src/hooks/useDisposableMemo.ts and trace how its effect cleanup disposes the memoized native value. Reproduce the hide and reveal behavior with React <Activity mode="hidden"> in production, then check the existing tests for this hook. Done means revealing the subtree leaves the value usable, with a regression test covering the lifecycle.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
React's <Activity mode="hidden"> runs a component's effect cleanups without unmounting it, and on reveal re-runs the effects with the same memoised values. In production builds useDisposableMemo disposes its value in that effect cleanup. After a hide and reveal the component still holds the disposed HybridObject, and the next call on it dereferences null in native code: release builds skip Nitro's null-NativeState check. Any app that hides a subtree containing a Rive view with <Activity> (React 19.2+) can hit this. We do it for inactive screens and for an animated mascot.
Versions
@rive-app/react-native0.5.5 (RiveRuntime iOS 6.28.1, rive-android 11.12.1).src/hooks/useDisposableMemo.tsonmainhas the same cleanup.react-native-nitro-modules0.36.5, React Native 0.88.0, React 19.3.0, Expo SDK 58, new architecture, Hermes.
What we see (production, about 8 days)
| iOS | Android | |
|---|---|---|
| Crashes / users | 35 / 35 | 38 / 37 |
| OS | iOS 17.6 – 27.0.1 | Android 11 – 17 |
| Devices | iPhones and iPads | moto g35 / g85, Lenovo Tab TB330FU / TB328FU, Samsung A05 / A16 / A52s, vivo, Xiaomi |
Each crash is the first call on a view-model instance, or on a property taken from it, after the subtree is shown again. Breadcrumbs show a navigation back to the screen just before.
iOS (EXC_BAD_ACCESS, address 0, JS thread)
hermes::vm::NativeFunction::_nativeCall
margelo::nitro::HybridFunction::createHybridFunction<…>::lambda::operator() (HybridFunction.hpp:119)
margelo::nitro::HybridFunction::callMethod<…> (HybridFunction.hpp:175)
Android (SIGSEGV)
facebook::react::RuntimeScheduler_Modern::executeTask
facebook::jsi::Function::call
margelo::nitro::HybridFunction::createHybridFunction<…>::lambda::operator() (HybridFunction.hpp:119)
margelo::nitro::HybridFunction::callMethod<…> (HybridFunction.hpp:179)
Root cause
useEffect(() => {
…
return () => {
if (__DEV__) { /* deferred with setTimeout(0), cancelled if the effect re-runs */ }
else {
cleanupRef.current(ref.current.value); // disposes now
}
};
}, []);
return ref.current.value; // the same, now dead, value after the reveal
The __DEV__ branch survives Strict Mode and Fast Refresh because the re-run effect cancels the pending disposal. The production branch has no equivalent, and <Activity> reaches it in production. This is the mechanism of #407 (fixed for useRiveList in #408), but in the shared hook, so it reaches useViewModelInstance and every hook built on it.
Suggested fix
Don't dispose in the effect cleanup. Dispose when the deps change (already done during render), and on a real unmount let the native object go when the JS wrapper is collected. Alternatives:
- keep the dev-style deferred disposal in production, cancelled when the effect re-runs;
- mark the value stale in the cleanup so the next render creates a fresh one.
We carry the first option as a local patch (not released yet), with a unit test of the hide-and-reveal case.
Related (cause not confirmed)
After the same hide and reveal, riveViewRef from useRive() is still non-null, but riveViewRef.play / .pause are undefined: "TypeError: undefined is not a function" when an effect that <Activity> re-runs calls them. We saw about 2,450 of these from about 750 users before guarding the calls on our side. It might help to clear the ref, or keep its methods callable, while the view is hidden.
- Ngôn ngữ chính
- TypeScript
- Star
- 158
- Fork
- 17
- Merge trung bình
- 4 ngày 4 giờ
- Pull request đã merge (30 ngày)
- 23
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của rive-app/rive-nitro-react-native
-
android bug enhancement iOS
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 44/100
rive-app/rive-nitro-react-native#445 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
rive-app/rive-nitro-react-native#424 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Rive drains battery in the background on AndroidCó thể đã có người làm @mfazekas đã nhận 28 ngày trước. Đang mởandroid bug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
rive-app/rive-nitro-react-native#413 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement iOS
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
rive-app/rive-nitro-react-native#58 · 7 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của rive-app/rive-nitro-react-native
Issue tương tự
-
FR: Support CJK brackets, symbols and full-width markers in footnoteHeuristics (EBPAJ support)Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
readest/readest#7413 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
content triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
eliasstravik/herdr-projects#788 ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Ability to edit tagsĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 1 ngày