Open tamacroft opened 3 weeks ago
This one is reported in react-native-screens and in Expo as well.
I've done some research and created a reproduction here.
A report was made in the RNScreens issue that this was working when using REA 3.14.0
and failed starting from REA 3.15.0
.
After investigating the commits between the two releases I was able to find the offending PR here:
https://github.com/software-mansion/react-native-reanimated/pull/6214
This one is containing an optimization to how shadow nodes are updated and if we revert this optimization (even tried reverting it from 3.16.1 by doing some manual copy/paste) the issues is no longer happening.
bartlomiejbloniarz - would you be able to take a look?
This is related to the new architecture only.
Putting here the visual recap of the impact on my app, from the Expo issue:
@chrfalch Thanks for this investigation! I will take it from here.
@chrfalch Thanks for this investigation! I will take it from here.
Awesome! Thanks :)
@bartlomiejbloniarz hi, after upgrading to 0.76 I faced the same issue on Paper, for some reason the modal won't show up only on iOS though.
Can't give a reproducer since the code around showing the modal is kinda complex: an element is highlighted with:
react-native-ui-lib
dialogTried with different dialog components just in case react-native-ui-lib one is problematic, no luck, used rn Modal, no luck.
edit: When I display the dialog without the reanimated svg rect the dialog shows up just fine 🤷♂️
edit2: under some unknown circumstances, when hot reloading the Dialog shows up, feels like it's one commit behind.
@efstathiosntonas Could you open a separate issue for that? In this one the Modal
actually shows up, but some of its content is not visible. Also, the reason for this issue is heavily New Architecture dependent, so I don't think those problems could be related.
@chrfalch I am still working on a solution. I have a (seemingly) working approach, but I'm still not 100% sure if it won't break anything.
The issue is that the non-visible content is actually rendered outside of the screen. This happens, because the Modal
has wrong height. Usually the height is stored in the c++ state of RNSModalScreen
and is updated after RNScreens obtain the height from iOS (this is why sometimes you can see a layout shift when a screen with a header is mounted).
Reanimated uses ReanimatedCommitHook
to apply our animation changes on top of RN changes. To apply our changes, we clone ShadowNodes
with new props. But whenever we clone a ShadowNode
that has not been mounted, YogaLayoutableShadowNode
re-clones all of its children. When cloning, RN uses the last mounted state, meaning that it actually overrides the height assigned by RNScreens, with wrong value.
Reverting the changes of #6214 doesn't actually solve the problem, as the old algorithm has the exact same flaw (but only in Release mode).
Thanks!! Really appreciate you working on this @bartlomiejbloniarz - I didn't catch the release issue - so this was a good find.
I am not sure that I understand the conversation here, I am having this issue with Android only. My app is on RN 0.76.2 and all dialogs/modals/bottom sheets are broken as they either do not show up or they get stuck all smushed in the top left corner and the whole screen becomes unusable. Is there a fix for this or something I can patch to make it work for now?
I am not sure that I understand the conversation here, I am having this issue with Android only. My app is on RN 0.76.2 and all dialogs/modals/bottom sheets are broken as they either do not show up or they get stuck all smushed in the top left corner and the whole screen becomes unusable. Is there a fix for this or something I can patch to make it work for now?
The only way I managed to fix this at is to just not have useAnimatedStyle
used anywhere when a modal is shown.
Hi I have a related issue with Animated.View
+ Modal
,
in my case the screen is not cropped, but the modal has 0
width and 0
height, unless they are explicitly set.
import { useState } from "react";
import { Button, Modal, SafeAreaView, StatusBar, View } from "react-native";
import Animated, { useAnimatedStyle } from "react-native-reanimated";
export default function App() {
const [visible, setVisible] = useState(false);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: 0 }],
}));
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: "#fff",
padding: 16,
}}
>
<StatusBar />
<View
style={{
paddingVertical: 16,
}}
/>
<Button
title="Open Modal"
onPress={() => {
setVisible(true);
}}
/>
<Animated.View style={animatedStyle} />
<Modal visible={visible} animationType="slide">
<View
style={{
padding: 32,
backgroundColor: "pink",
}}
></View>
</Modal>
</SafeAreaView>
);
}
Description
before Im upgrade to react native 0.76.1(new arch), Im using react native 0.75.4 and its work fine with old arch. I have trace error why my modal children is not rendered, because i have useAnimatedStyle in component where my modal placed. When i disabled useAnimatedStyle, its not break modal
Steps to reproduce
Snack or a link to a repository
https://snack.expo.dev/@tamacroft_expo/2fd4f5
Reanimated version
3.16.1
React Native version
0.76.1
Platforms
Android
JavaScript runtime
Hermes
Workflow
React Native
Architecture
Fabric (New Architecture)
Build type
Debug app & production bundle
Device
Android emulator
Device model
No response
Acknowledgements
Yes