Skip to content

Commit

Permalink
fix: change default value of context of ScreenGestureDetector, add wa…
Browse files Browse the repository at this point in the history
…rning for goBackGesture (software-mansion#2013)

## Description
Previously, after going from one screen to another (or after opening the
app) there was an error regarding ScreenGestureDetector:

`Warning: Invalid prop 'gestureDetectorBridge' supplied to
'React.Fragment'. React.Fragment can only have 'key' and 'children'
props.`

This error indicates that we were passing props from
ScreenGestureDetector to React.Fragment. Indeed, after looking onto the
default value of GHContext, there was a Fragment that was receiving
invalid props.
This PR fixes this by changing the look of React.Fragment, so we won't
pass the props further.

Also, I've added a warning that is being shown when user tries to use
`goBackGesture` and the navigator is not wrapped in
ScreenGestureDetector.

Fixes software-mansion#2010.

## Changes

- Fix warning of React.Fragment when the ScreenGestureDetector isn't
mounted
- Add warning when user tries to use `goBackGesture` and the navigator
is not wrapped in ScreenGestureDetector
- Reformated code a bit

## Screenshots / GIFs

### Before


https://github.com/software-mansion/react-native-screens/assets/23281839/f3517b73-de80-45a5-847e-bd817d3d2682

### After

Video shows behavior on going from one screen to another and a warning
when there's prop `goBackGesture` without ScreenGestureProvider.


https://github.com/software-mansion/react-native-screens/assets/23281839/7b477ea6-08cc-40ed-afd5-879675776007

## Test code and steps to reproduce

You can test the changes in a several ways:
- By checking Screen animation example from ScreensExample
- By checking Test42 from TestsExample
- By checking TestScreenAnimation from FabricTestExample

## Checklist

- [X] Included code example that can be used to test this change
- [x] Ensured that CI passes
  • Loading branch information
tboba authored and ja1ns committed Oct 9, 2024
1 parent 8060a48 commit 372776f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
12 changes: 4 additions & 8 deletions src/index.native.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import React, {
Fragment,
PropsWithChildren,
ReactNode,
useEffect,
useRef,
} from 'react';
import React, { PropsWithChildren, ReactNode, useEffect, useRef } from 'react';
import {
Animated,
Image,
Expand Down Expand Up @@ -581,7 +575,9 @@ export type {
const ScreenContext = React.createContext(InnerScreen);

// context to be used when the user wants full screen swipe (see `gesture-handler` folder in repo)
const GHContext = React.createContext(Fragment);
const GHContext = React.createContext(
(props: { children: React.ReactNode }) => <>{props.children}</>
);

class Screen extends React.Component<ScreenProps> {
static contextType = ScreenContext;
Expand Down
20 changes: 16 additions & 4 deletions src/native-stack/views/NativeStackView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ function NativeStackViewInner({
const { key, routes } = state;

const currentRouteKey = routes[state.index].key;
const topScreenOptions = descriptors[currentRouteKey].options;
const { goBackGesture, transitionAnimation, screenEdgeGesture } =
descriptors[currentRouteKey].options;
const gestureDetectorBridge = React.useRef<GestureDetectorBridge>({
stackUseEffectCallback: _stackRef => {
// this method will be override in GestureDetector
Expand All @@ -432,12 +433,23 @@ function NativeStackViewInner({
const screensRefs = React.useRef<RefHolder>({});
const ScreenGestureDetector = React.useContext(GHContext);

React.useEffect(() => {
if (
ScreenGestureDetector.name !== 'GHWrapper' &&
goBackGesture !== undefined
) {
console.warn(
'Cannot detect GestureDetectorProvider in a screen that uses `goBackGesture`. Make sure your navigator is wrapped in GestureDetectorProvider.'
);
}
}, [ScreenGestureDetector.name, goBackGesture]);

return (
<ScreenGestureDetector
gestureDetectorBridge={gestureDetectorBridge}
goBackGesture={topScreenOptions?.goBackGesture}
transitionAnimation={topScreenOptions?.transitionAnimation}
screenEdgeGesture={topScreenOptions?.screenEdgeGesture ?? false}
goBackGesture={goBackGesture}
transitionAnimation={transitionAnimation}
screenEdgeGesture={screenEdgeGesture ?? false}
screensRefs={screensRefs}
currentRouteKey={currentRouteKey}>
<ScreenStack
Expand Down

0 comments on commit 372776f

Please sign in to comment.