react-native
react-native copied to clipboard
Modal/Bottomsheet UI glitches in new architecture
Description
when we open the Modal from the default react native, or any overlay component, there is a glitch in the UI and the content given sits on the top left of the UI, this happens preciously, missing consistency
Steps to reproduce
- install the new application with React native version 0f 0.79.1,
- create a modal with some content and center the modal with some styling
- open the modal using any state and we can notice the glitch in the UI
React Native Version
0.79.1
Affected Platforms
Runtime - Android
Output of npx @react-native-community/cli info
warn Package rn-fetch-blob contains invalid configuration: "dependency.hooks" is not allowed. Please verify it's properly linked using "npx react-native config" command and contact the package maintainers about this.
info Fetching system and libraries information...
System:
OS: Windows 11 10.0.26100
CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1155G7 @ 2.50GHz
Memory: 1.65 GB / 11.65 GB
Binaries:
Node:
version: 22.11.0
path: C:\Program Files\nodejs\node.EXE
Yarn: Not Found
npm:
version: 10.9.0
path: C:\Program Files\nodejs\npm.CMD
Watchman: Not Found
SDKs:
Android SDK:
API Levels:
- "33"
- "34"
- "35"
Build Tools:
- 30.0.3
- 33.0.0
- 33.0.1
- 34.0.0
- 35.0.0
System Images:
- android-31 | Google Play Intel x86_64 Atom
- android-33 | Google Play Intel x86_64 Atom
- android-35 | Google APIs Intel x86_64 Atom
Android NDK: Not Found
Windows SDK: Not Found
IDEs:
Android Studio: AI-241.18034.62.2411.12169540
Visual Studio: Not Found
Languages:
Java: 17.0.13
Ruby: Not Found
npmPackages:
"@react-native-community/cli":
installed: 18.0.0
wanted: 18.0.0
react:
installed: 19.0.0
wanted: 19.0.0
react-native:
installed: 0.79.1
wanted: 0.79.1
react-native-windows: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
info React Native v0.79.2 is now available (your project is running on v0.79.1).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.79.2
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.79.1&to=0.79.2
info For more info, check out "https://reactnative.dev/docs/upgrading?os=windows".
Stacktrace or Logs
no crashes
MANDATORY Reproducer
no required
Screenshots and Videos
[!WARNING] Missing reproducer: We could not detect a reproducible example in your issue report. Reproducers are mandatory and we can accept only one of those as a valid reproducer:
- For majority of bugs: send us a Pull Request with the RNTesterPlayground.js edited to reproduce your bug.
- If your bug is UI related: a Snack
- If your bug is build/upgrade related: a project using our Reproducer Template
You can read more about about it on our website: How to report a bug.
@kowsickram24 It will be great if you can share a reproducer as it will help us to narrow down the issue.
I can confirm - the same issue exists on 0.76.9 and 0.77.2.
I can confirm - the same issue exists on 0.76.9 and 0.77.2.
Can you add the reproducer they ask @3plusalpha
It is caused by react-navigation. Here is a quick fix: https://github.com/expo/expo/issues/32991#issuecomment-2489620459
It is caused by react-navigation. Here is a quick fix: expo/expo#32991 (comment)
actually, there is an issue in the Modal component provided by react native in the latest version, not caused by react-navigation @3plusalpha
@kowsickram24 I tried to reproduce the bug with the Reproducer Template, but it works like expected.
In my other app the bug appears though, so I suspect that a surrounding view like the stack navigator of react-navigation is causing the issue.
Could you post the packages you are using?
{ "name": "ayushya", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", "lint-fix": "eslint --fix", "start": "react-native start", "test": "jest" }, "dependencies": { "@react-native-documents/picker": "^10.1.3", "@react-navigation/native": "^7.1.6", "@react-navigation/native-stack": "^7.3.13", "@reduxjs/toolkit": "^2.7.0", "@simform_solutions/react-native-audio-waveform": "^2.1.5", "formik": "^2.4.6", "google-libphonenumber": "^3.2.40", "libphonenumber-js": "^1.12.7", "lottie-react-native": "^7.2.2", "prop-types": "^15.8.1", "react": "19.0.0", "react-native": "0.79.1", "react-native-confirmation-code-field": "^7.4.0", "react-native-country-codes-picker": "^2.3.5", "react-native-dotenv": "^3.4.11", "react-native-dropdown-picker": "^5.4.6", "react-native-encrypted-storage": "^4.0.3", "react-native-fs": "^2.20.0", "react-native-gesture-handler": "^2.25.0", "react-native-image-crop-picker": "^0.42.0", "react-native-linear-gradient": "^2.8.3", "react-native-paper": "^5.13.4", "react-native-permissions": "^5.3.0", "react-native-reanimated": "^3.17.4", "react-native-responsive-screen": "^1.4.2", "react-native-safe-area-context": "^5.4.0", "react-native-screens": "^4.10.0", "react-native-svg": "^15.11.2", "react-native-svg-transformer": "^1.5.0", "react-native-vector-icons": "^10.2.0", "react-redux": "^9.2.0", "redux": "^5.0.1", "unimported": "^1.31.1", "yup": "^1.6.1" }, "devDependencies": { "@babel/core": "^7.25.2", "@babel/preset-env": "^7.25.3", "@babel/runtime": "^7.25.0", "@react-native-community/cli": "18.0.0", "@react-native-community/cli-platform-android": "18.0.0", "@react-native-community/cli-platform-ios": "18.0.0", "@react-native/babel-preset": "0.79.1", "@react-native/eslint-config": "0.79.1", "@react-native/metro-config": "0.79.1", "@react-native/typescript-config": "0.79.1", "@types/jest": "^29.5.13", "@types/react": "^19.0.0", "@types/react-test-renderer": "^19.0.0", "eslint": "^8.19.0", "eslint-plugin-react": "^7.37.5", "jest": "^29.6.3", "prettier": "2.8.8", "react-test-renderer": "19.0.0", "typescript": "5.0.4" }, "engines": { "node": ">=18" } } package.json @3plusalpha
From your package.json I see you are using @react-navigation/native-stack. As mentioned before the modal issues is likely caused by the navigation library.
Try the fix from here https://github.com/expo/expo/issues/32991#issuecomment-2489620459:
<View style={{ width: "100%", height: "100%", position: "absolute" }}>
<Modal transparent visible={showModal}>
{children}
</Modal>
</View>```
import React from "react";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
const Modal = ({ visible, children }) => { return visible ? ( <Animated.View style={{ position: "absolute", top: 0, left: 0, right: 0, bottom: 0, zIndex: 999, backgroundColor: "rgba(0,0,0,0.5)", }} entering={FadeIn} exiting={FadeOut} > <Animated.View entering={FadeIn} exiting={FadeOut} style={{ flex: 1, justifyContent: "center", alignItems: "center" }} > {children} </Animated.View> </Animated.View> ) : null; };
export default React.memo(Modal); I used this reusable component, but the actual Modal still glitches @3plusalpha
I also get a bug when I set swipeDirection, it shows the interface then hides it, then the animationIn effect happens. This happens very quickly and is very annoying.
I have applied the solution which @3plusalpha is given still my issue is not fixed i am using react-native 0.78.2 version below i have attached my code anyone know how to fix this?
import React, { useEffect } from "react";
import { View, StyleSheet, Text, Modal } from "react-native";
import Animated, {
useSharedValue,
useAnimatedStyle,
withRepeat,
withTiming,
cancelAnimation,
Easing,
} from "react-native-reanimated";
import { scale } from "react-native-size-matters";
import appFonts from "../utils/theme";
import Colors from "../theme/colors";
const Loader = ({
size = scale(40),
color = Colors.white,
loading,
text = "Loading...",
}) => {
const rotation = useSharedValue(0);
useEffect(() => {
if (loading) {
rotation.value = withRepeat(
withTiming(360, {
duration: 400,
easing: Easing.linear,
}),
-1,
false
);
} else {
cancelAnimation(rotation);
rotation.value = 0;
}
return () => {
cancelAnimation(rotation);
rotation.value = 0;
};
}, [loading]);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ rotate: `${rotation.value}deg` }],
}));
return (
<View
style={{
width: "100%",
height: "100%",
position: "absolute",
backgroundColor: "transparent",
}}
>
<Modal
transparent
visible={loading}
animationType="fade"
statusBarTranslucent
>
<View style={styles.modalBackground}>
<View style={styles.loaderView}>
<Animated.View
style={[
styles.spinner,
animatedStyle,
{
width: size,
height: size,
borderRadius: size / 2,
borderTopColor: color,
borderRightColor: color,
borderBottomColor: "#ffffff40",
borderLeftColor: "#ffffff10",
},
]}
/>
<Text style={styles.text}>{text}</Text>
</View>
</View>
</Modal>
</View>
);
};
const styles = StyleSheet.create({
modalBackground: {
flex: 1,
backgroundColor: Colors.transparentColor,
justifyContent: "center",
alignItems: "center",
},
loaderView: {
backgroundColor: Colors.black500,
padding: scale(25),
borderRadius: scale(10),
alignItems: "center",
elevation: scale(10),
shadowColor: Colors.white,
shadowOffset: { width: scale(0), height: scale(0) },
shadowOpacity: scale(0.7),
shadowRadius: scale(10),
},
spinner: {
borderWidth: scale(4),
borderStyle: "solid",
},
text: {
color: Colors.white,
marginTop: scale(10),
fontFamily: appFonts.poppins_bold,
fontSize: scale(12),
},
});
export default Loader;