Snackbar stays mounted after `visible=false` under new architecture (iOS + Android)
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 78/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Tranquilla
- Stack tecnologico
- react-native, typescript
- Ambito
- mobile
Direzione di ricerca
Leggi src/components/Snackbar.tsx, concentrandoti su handleOnHidden e sul callback dell’animazione di nascondimento; confronta il suo comportamento con il workaround del percorso di visualizzazione in #4447. Riproduci il problema con Fabric abilitato impostando visible da true a false su iOS o Android. Il lavoro è completato quando l’animazione di nascondimento lascia la Snackbar smontata e nascosta anche quando il callback segnala finished: false.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Under React Native's new architecture (Fabric), paper's <Snackbar> can get stuck mounted at non-zero opacity after visible is set to false. The hide animation runs visually, but the component never unmounts and stays visible on screen until something else forces a remount.
Sister bug to #3775 / #4445 (which were Android-only show path, fixed by #4447). This is the hide path, and reproduces on both iOS and Android with the new arch enabled.
Root cause
src/components/Snackbar.tsx, handleOnHidden:
Animated.timing(opacity, {
toValue: 0,
duration: 100 * scale,
useNativeDriver: true,
}).start(({ finished }) => {
if (finished) { // ← this guard is the problem under Fabric
setHidden(true);
}
});
Under Fabric, this start({finished}) callback fires with finished: false even when nothing has interrupted the animation. setHidden(true) is the only thing that makes the component return null and actually unmount, so the snackbar stays rendered at whatever opacity the (visually-running) animation reached.
The parallel show-path fix #4447 split handleOnVisible from animateShow to work around the same Fabric noise. The hide path was not touched and still carries the guard.
Expected behaviour
After visible={false}, the Snackbar component unmounts cleanly (hidden flips to true) once the hide animation completes, regardless of the finished flag.
Current behaviour
After visible={false}:
- The hide animation fires (opacity 1 → 0).
- The
startcallback fires withfinished: false. setHidden(true)is skipped.- The component stays mounted; nothing in the React state can clear it.
- Subsequent
setVisible(false)taps re-trigger the same broken animation; the snackbar never goes away.
Repro
- New arch enabled.
- Mount a global
<Snackbar visible={visible} onDismiss={() => setVisible(false)} action={{ label: 'Action', onPress: () => {} }}>Message</Snackbar>. setVisible(true), thensetVisible(false).- Snackbar stays on screen.
Reproduced on:
- iOS 18 simulator (iPhone 15)
- iOS 26 simulator (iPhone 17 Pro Max)
- Android Pixel 8 emulator (API 35)
All with newArchEnabled: true.
Environment
react-native-paper: 5.15.2react-native: 0.83.6- Expo SDK 55
- Fabric / new arch: enabled
Proposed fix
Drop the if (finished) guard, mirroring how #4447 worked around the same class of Fabric noise on the show path:
Animated.timing(opacity, {
toValue: 0,
duration: 100 * scale,
useNativeDriver: true,
- }).start(({ finished }) => {
- if (finished) {
- setHidden(true);
- }
+ }).start(() => {
+ setHidden(true);
});
Trade-off
Under a genuine interrupt (a new show kicked off mid-hide), setHidden(true) would now also fire. The next render uses the new visible=true path → setHidden(false) → re-animates show. The visible artefact is at worst a one-frame snap. A stuck Snackbar that no state change can clear is strictly worse.
Happy to open a PR if useful. Tested locally via patch-package; resolves the issue on both platforms.
- Lingua principale
- TypeScript
- Stelle
- 14.5k
- Fork
- 2.2k
- Merge medio
- 3g 22h
- PR unite (30g)
- 8
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di callstack/react-native-paper
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
callstack/react-native-paper#5096 ·
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
callstack/react-native-paper#5093 ·
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
callstack/react-native-paper#5003 ·
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
callstack/react-native-paper#4881 ·
I maintainer di solito rispondono entro 2 giorni
-
feature request
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
callstack/react-native-paper#4863 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di callstack/react-native-paper
Issue simili
-
keytrace logo svg?Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
cyclofinance/cyclo.site#448 ·
-
[sanity-plugin-media] Searching for a word with an apostrophe shows an error instead of resultsAperta@sanity-io/studio bug sanity-plugin-media Sieve-Agent
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
-
bug via-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
pingdotgg/t3code#15221 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno