From 48dbcf58ac5d4e8143962745813e06de6148bfee Mon Sep 17 00:00:00 2001 From: kacperkapusciak Date: Wed, 20 Jul 2022 09:58:54 +0200 Subject: [PATCH 1/3] fix: wrap screen with screen context --- src/index.native.tsx | 16 +++++++++++++--- src/index.tsx | 2 ++ src/reanimated/ReanimatedNativeStackScreen.tsx | 4 ++-- src/reanimated/ReanimatedScreen.tsx | 4 ++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/index.native.tsx b/src/index.native.tsx index b3b9abbee0..f936de80b0 100644 --- a/src/index.native.tsx +++ b/src/index.native.tsx @@ -200,7 +200,7 @@ interface ViewConfig extends View { }; } -class Screen extends React.Component { +class InnerScreen extends React.Component { private ref: React.ElementRef | null = null; private closing = new Animated.Value(0); private progress = new Animated.Value(0); @@ -408,8 +408,17 @@ export type { }; // context to be used when the user wants to use enhanced implementation -// e.g. to use `react-native-reanimated` (see `reanimated` folder in repo) -const ScreenContext = React.createContext(Screen); +// e.g. to use `useReanimatedTransitionProgress` (see `reanimated` folder in repo) +const ScreenContext = React.createContext(InnerScreen); + +class Screen extends React.Component { + static contextType = ScreenContext; + + render() { + const ScreenWrapper = this.context || InnerScreen; + return ; + } +} module.exports = { // these are classes so they are not evaluated until used @@ -418,6 +427,7 @@ module.exports = { ScreenContainer, ScreenContext, ScreenStack, + InnerScreen, get NativeScreen() { return ScreensNativeModules.NativeScreen; diff --git a/src/index.tsx b/src/index.tsx index 573e68dc52..9502a36694 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -62,6 +62,8 @@ export class NativeScreen extends React.Component { export const Screen = Animated.createAnimatedComponent(NativeScreen); +export const InnerScreen = View; + export const ScreenContext = React.createContext(Screen); export const ScreenContainer: React.ComponentType = View; diff --git a/src/reanimated/ReanimatedNativeStackScreen.tsx b/src/reanimated/ReanimatedNativeStackScreen.tsx index 01691b822a..bbd18552c1 100644 --- a/src/reanimated/ReanimatedNativeStackScreen.tsx +++ b/src/reanimated/ReanimatedNativeStackScreen.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Platform } from 'react-native'; import { - Screen, + InnerScreen, ScreenProps, TransitionProgressEventType, } from 'react-native-screens'; @@ -11,7 +11,7 @@ import Animated, { useEvent, useSharedValue } from 'react-native-reanimated'; import ReanimatedTransitionProgressContext from './ReanimatedTransitionProgressContext'; const AnimatedScreen = Animated.createAnimatedComponent( - (Screen as unknown) as React.ComponentClass + (InnerScreen as unknown) as React.ComponentClass ); // We use prop added to global by reanimated since it seems safer than the one from RN. See: diff --git a/src/reanimated/ReanimatedScreen.tsx b/src/reanimated/ReanimatedScreen.tsx index e55eeb62c9..76dce1f9ee 100644 --- a/src/reanimated/ReanimatedScreen.tsx +++ b/src/reanimated/ReanimatedScreen.tsx @@ -1,11 +1,11 @@ import React from 'react'; -import { Screen, ScreenProps } from 'react-native-screens'; +import { InnerScreen, ScreenProps } from 'react-native-screens'; // @ts-ignore file to be used only if `react-native-reanimated` available in the project import Animated from 'react-native-reanimated'; const AnimatedScreen = Animated.createAnimatedComponent( - (Screen as unknown) as React.ComponentClass + (InnerScreen as unknown) as React.ComponentClass ); const ReanimatedScreen = React.forwardRef( From c3a62ac2c17f5143203b925e8d7eb5bd80e99e81 Mon Sep 17 00:00:00 2001 From: kacperkapusciak Date: Wed, 20 Jul 2022 10:09:23 +0200 Subject: [PATCH 2/3] chore: add reproduction --- TestsExample/App.js | 1 + TestsExample/src/Test1539.tsx | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 TestsExample/src/Test1539.tsx diff --git a/TestsExample/App.js b/TestsExample/App.js index 888abca221..26e3db3336 100644 --- a/TestsExample/App.js +++ b/TestsExample/App.js @@ -81,6 +81,7 @@ import Test1419 from './src/Test1419'; import Test1473 from './src/Test1473'; import Test1476 from './src/Test1476'; import Test1509 from './src/Test1509'; +import Test1539 from './src/Test1539'; enableFreeze(true); diff --git a/TestsExample/src/Test1539.tsx b/TestsExample/src/Test1539.tsx new file mode 100644 index 0000000000..dc52bb064d --- /dev/null +++ b/TestsExample/src/Test1539.tsx @@ -0,0 +1,58 @@ +import {NavigationContainer, useNavigation} from '@react-navigation/native'; +import {createNativeStackNavigator} from '@react-navigation/native-stack'; +import * as React from 'react'; +import { + ReanimatedScreenProvider, + useReanimatedTransitionProgress, +} from 'react-native-screens/reanimated'; +import Reanimated, { + useAnimatedStyle, + useDerivedValue, +} from 'react-native-reanimated'; +import {Button} from 'react-native'; + +export default function App() { + return ( + + + + + + + + + ); +} + +const Stack = createNativeStackNavigator(); + +function RootScreen() { + const {navigate} = useNavigation(); + const reaProgress = useReanimatedTransitionProgress(); + const sv = useDerivedValue( + () => + (reaProgress.progress.value < 0.5 + ? reaProgress.progress.value * 50 + : (1 - reaProgress.progress.value) * 50) + 50, + ); + const reaStyle = useAnimatedStyle(() => { + return { + width: sv.value, + height: sv.value, + backgroundColor: 'blue', + }; + }); + + return ( + <> + +