Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backdrop flashes on mount #208

Closed
Michael-M-Judd opened this issue Jan 18, 2021 · 28 comments · Fixed by #239
Closed

Backdrop flashes on mount #208

Michael-M-Judd opened this issue Jan 18, 2021 · 28 comments · Fixed by #239
Assignees
Labels
bug Something isn't working v2 Written in Reanimated v1

Comments

@Michael-M-Judd
Copy link

Bug

Adding a backdrop on v2 seems to causes the initial backdrop to flash on mount even though the modal is closed. You can see here, where once I tap "mount" it flashes the backdrop quickly. If I remove the backdrop, it doesn't show up. I've tried doing a custom, more basic backdrop and it doesn't seem to work either (same thing). Note: it's fairly quick here, but in a larger app it seems to take even longer to disappear

Kapture 2021-01-15 at 08 43 53

I did notice that this issue #118 seems to be related, but I'm on the latest version and still having issues. I tried adding some debugging logs but couldn't get more from it. I have a feeling it's related to the animatedIndex value being passed in? That value controls opacity of the backdrop and if it's not 0 on mount it'll flash (what seems to be at full opacity).

Environment info

Library Version
@gorhom/bottom-sheet 2.0.3
react-native 0.63.4
react-native-reanimated 1.13.2
react-native-gesture-handler 1.9.0

Steps To Reproduce

Go to android (IOS doesn't have the problem on the snack simulator, but if you do it on real simulator or real device you'll see it, press mount, you'll see the screen flicker:

https://snack.expo.io/7UoD9PU0Z

Describe what you expected to happen:
On mount, if the modal is closed I.e. index === -1, we should not show the backdrop flash. The animation code is correct, but the mounting logic seems a little odd

Reproducible sample code

https://snack.expo.io/7UoD9PU0Z

@Michael-M-Judd Michael-M-Judd added the bug Something isn't working label Jan 18, 2021
@gorhom gorhom added the v2 Written in Reanimated v1 label Jan 18, 2021
@gorhom
Copy link
Owner

gorhom commented Jan 18, 2021

you could use BottomSheetModal for this use case, it handle mounting better

https://gorhom.github.io/react-native-bottom-sheet/modal

import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import BottomSheet, {
  BottomSheetModal,
  BottomSheetBackdrop,
  BottomSheetModalProvider,
} from '@gorhom/bottom-sheet';

const snapPoints = ['40%'];
const App = () => {
  // ref
  const bottomSheetModalRef = useRef<BottomSheetModal>(null);

  const [showModal, setShowModal] = useState(false);
  // callbacks
  const handlePresentModalPress = useCallback(() => {
    bottomSheetModalRef.current?.present();
  }, []);
  const handleSheetChanges = useCallback((index: number) => {
    console.log('handleSheetChanges', index);
  }, []);

  useEffect(() => {
    if(showModal) {
      bottomSheetModalRef.current?.present()
    }else{
      bottomSheetModalRef.current?.dismiss();
    }
  }, [showModal])

  // renders
  return (
    <BottomSheetModalProvider>
      <View style={styles.container}>
        {showModal ? (
          <Button onPress={handlePresentModalPress} title="Present Modal" />
        ) : null}
        <Button
          onPress={() => setShowModal(m => !m)}
          title={showModal ? 'Unmount modal' : 'Mount modal'}
        />
      </View>
      <BottomSheetModal
        ref={bottomSheetModalRef}
        snapPoints={snapPoints}
        onChange={handleSheetChanges}
        backdropComponent={BottomSheetBackdrop}
      >
        <View style={styles.contentContainer}>
          <Text>Awesome 🎉</Text>
        </View>
      </BottomSheetModal>
    </BottomSheetModalProvider>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    justifyContent: 'center',
    backgroundColor: 'white',
  },
  contentContainer: {
    flex: 1,
    alignItems: 'center',
  },
});

export default App;

@gorhom gorhom closed this as completed Jan 18, 2021
@ferrannp
Copy link

I am experiencing this bug too. Cannot use v3 and this seems a v2 bug too so... is this going to be fixed @gorhom ? Thought v2 is in maintenance mode for bugs like this one? Basically backdropComponent={BottomSheetBackdrop} makes content to flash when mounting.

@gorhom
Copy link
Owner

gorhom commented Jan 20, 2021

@ferrannp Dose it happened with 'BottomSheetModal' too ?

@ferrannp
Copy link

ferrannp commented Jan 20, 2021

It seems that no but with BottomSheetModal, you do not get the BottomSheetBackdrop to animate the background (less or more opacity) while you drag the sheet.

Edit: Mmm actually that seems another problem. If you have more than 2 SnapPoints and you snap to the first, there is no opacity changes in background from first to second... Gonna keep playing with it.

@gorhom if using the BottomSheetModal, I don't really have anymore access to useBottomSheet and I cannot call snapTo from inside right?

@gorhom
Copy link
Owner

gorhom commented Jan 20, 2021

@ferrannp try to modify BottomSheetBackdrop props

export interface BottomSheetDefaultBackdropProps
extends BottomSheetBackdropProps {
/**
* Backdrop opacity.
* @type number
* @default 0.5
*/
opacity?: number;
/**
* Snap point index when backdrop will appears on.
* @type number
* @default 1
*/
appearsOnIndex?: number;
/**
* Snap point index when backdrop will disappears on.
* @type number
* @default 0
*/
disappearsOnIndex?: number;
/**
* Enable touch through backdrop component.
* @type boolean
* @default false
*/
enableTouchThrough?: boolean;
/**
* Close sheet when user press on backdrop.
* @type boolean
* @default true
*/
closeOnPress?: boolean;
}

@gorhom
Copy link
Owner

gorhom commented Jan 20, 2021

@gorhom if using the BottomSheetModal, I don't really have anymore access to useBottomSheet and I cannot call snapTo from inside right?

you can !

@ferrannp
Copy link

ferrannp commented Jan 21, 2021

@gorhom the modal is just much slower to appear (because mount/unmounting) than the BottomSheet. This seems to work:

setTimeout(() => {
  setBackdropComponent(BottomSheetBackdrop);
    // TODO bug in BottomSheet that when it mounts, backdrop flashes
}, 250);

Pretty sure there is a way to fix this in v2 (like it is fix in v3).

Another thing that seems to work (maybe better):

const [backdropOpacity, setBackDropOpacity] = useState(0);
const renderBackdrop = useCallback(
  props => <BottomSheetBackdrop {...props} opacity={backdropOpacity} />,   [backdropOpacity]
);

Then:

setBackDropOpacity(0.5);
bottomSheetRef.current?.expand();

@gorhom
Copy link
Owner

gorhom commented Jan 21, 2021

hi @ferrannp , you do not need to update opacity of the BottomSheetBackdrop , this already been handled internally. this prop is to set the max opacity of the BottomSheetBackdrop and it will be interpolated

const animatedOpacity = useMemo(
() =>
interpolate(animatedIndex, {
inputRange: [disappearsOnIndex, appearsOnIndex],
outputRange: [0, opacity],
extrapolate: Extrapolate.CLAMP,
}),
[animatedIndex, opacity, appearsOnIndex, disappearsOnIndex]
);

i think it get slower because of setting the opacity and that caused the whole re-rendering the sheet.

@theohdv
Copy link

theohdv commented Jan 26, 2021

I agree with @ferrannp I have the same issue on v2. It's a little bit better using BottomSheetModal but when you call present() function you can notice a flash on the backdrop. And the cons is that BottomSheetModal is slower to appear as it is Mount/UnMount on each call.

I think this issue should be reopen.

@ferrannp
Copy link

@theohdv this is my workaround if you are interested:

const [backdropOpacity, setBackDropOpacity] = useState(0);

const renderBackdrop = useCallback(
  props => <BottomSheetBackdrop {...props} opacity={backdropOpacity} />, 
  [backdropOpacity]
);

<BottomSheet
  backdropComponent={renderBackdrop}
  ...

Then before calling expand:

if (backdropOpacity === 0) {
  setBackDropOpacity(0.5);
}
bottomSheetRef.current?.expand();

In this way you do not see the flash when mounting it.

@theohdv
Copy link

theohdv commented Jan 27, 2021

Thanks for the tips, but in my case I cannot use this workaround because expand() is called in a parent component (or I have to set backdropOpacity as a props).

But I tried to call setBackDropOpacity(0.5); in a useEffect with a timeout but the flash still happens with a delay :/

@gorhom
Copy link
Owner

gorhom commented Jan 27, 2021

@theohdv could you share a reproducible sample code of your use case and i will look into it

@theohdv
Copy link

theohdv commented Jan 27, 2021

Ok it is working well when handleComponent is not overriden.

Reproducible sample:
https://snack.expo.io/@theohdv/tenacious-banana

It is 2 different issues, so I can open a new issues for this one if you want. But I think this issue should be reopen as it's a real bug (and using BottomsheetModal component is a workaround not a fix).

Screen.Recording.2021-01-27.at.11.35.03.mov

@gorhom
Copy link
Owner

gorhom commented Jan 27, 2021

thanks @theohdv for providing the reproducible snack ! i will look into it later today

@gorhom gorhom reopened this Jan 27, 2021
@gorhom gorhom self-assigned this Jan 27, 2021
@hanno-ferrannegre
Copy link

@gorhom not sure if related but I tried v3 and when you use this example from docs: https://gorhom.github.io/react-native-bottom-sheet/usage even even if not using backdrop, if the BS is initially mounted (first screen) it also flashes. You can just reload JS and you see it flashes.

@gorhom
Copy link
Owner

gorhom commented Jan 27, 2021

hi @ferrannp , @theohdv & @Michael-M-Judd i have submitted a pr to fix this issue on BottomSheet & BottomSheetModal please give it a try and let me know :)

#239

@gorhom
Copy link
Owner

gorhom commented Jan 27, 2021

@gorhom not sure if related but I tried v3 and when you use this example from docs: https://gorhom.github.io/react-native-bottom-sheet/usage even even if not using backdrop, if the BS is initially mounted (first screen) it also flashes. You can just reload JS and you see it flashes.

i will investigate it shortly

@ferrannp
Copy link

@gorhom I tried your PR for v2 and it seems to work just fine 👍 🥳 .

@theohdv
Copy link

theohdv commented Jan 29, 2021

@gorhom when did you plan to release those fixes ?

@gorhom
Copy link
Owner

gorhom commented Jan 29, 2021

hi @theohdv , i am trying to fit #244 with this release , so hopefully later today 🤞

@ferrannp
Copy link

@gorhom any idea how to prevent this flash on mount for v3 ?

@saaymeen
Copy link

Still existing today, I have the BottomSheet mounted in a page as initially closed but when I navigate to the screen, the backdrop flashes.

@theMasix
Copy link

theMasix commented Apr 22, 2021

Same here! using BottomSheetModal on v2.3

Backdrop flashing occurs on First mounting of modal. But other mountings doesn't have this issue. probably relevant to react-native-portal package. maybe!

@gorhom

@theMasix
Copy link

theMasix commented Apr 29, 2021

I just fixed the issue. It was all about snapPoints!

Backdrop flashes if I provide:

  • snapPoints: [contentHeight] (with useMemo)
  • index: 0
  • without appearsOnIndex and disappearsOnIndex on backdrop

But doesn't have any flashing if I provide:

  • snapPoints: [0, contentHeight] (with useMemo)
  • index: 1
  • appearsOnIndex:2 and disappearsOnIndex:1 on backdrop

I just shifted all values and snapPoints by one and it fixed the issue. So I think it's a bug about how the package handles snapPoints or appearsOnIndex and disappearsOnIndex

Note: backdrop animation doesn't have any differenece between two configs, the only difference is that in first config, backdrop flashes on first mount only.

@nickprihodko
Copy link

Hi, @gorhom! Any updates for this issue? Thanks

@gorhom
Copy link
Owner

gorhom commented Sep 11, 2021

@nickprihodko could you create a new issue and provide a new reproducible sample code following the template issue, thanks

@gorhom gorhom reopened this Sep 11, 2021
@gorhom gorhom closed this as completed Sep 11, 2021
@hardik-javascript
Copy link

I also have this issue using BottomSheetModal and with only single snapPoint backdrop doesn't show so i took suggestion of @theMasix and used onChange method to close modal when it dragged down to first index

import React, { useCallback, useRef } from 'react';
import { Text, TouchableOpacity } from 'react-native';
import {
	BottomSheetBackdrop,
	BottomSheetBackdropProps,
	BottomSheetModal
} from '@gorhom/bottom-sheet';


const DropdownMobile = () => {
	const bottomSheetModalRef = useRef<BottomSheetModal>(null);

	const handlePresentModalPress = useCallback(() => {
		bottomSheetModalRef.current?.present();
	}, []);

	const handleDrag = (index: number) => {
		if(index === 0) bottomSheetModalRef.current?.close();
	};

	const renderBackdrop = useCallback((props: BottomSheetBackdropProps) => <BottomSheetBackdrop
		{...props}
		pressBehavior={'close'}
		opacity={0.4}
		appearsOnIndex={1}
	/>, []);

	return (
		<>
			<TouchableOpacity onPress={handlePresentModalPress}>
				<Text>Open</Text>
			</TouchableOpacity>
			<BottomSheetModal
				ref={bottomSheetModalRef}
				index={1}
				snapPoints={[1,360]}
				backdropComponent={renderBackdrop}
				onChange={handleDrag}
			>
				...
			</BottomSheetModal>
		</>
	);
};

@CarlMenke
Copy link

to anyone experiencing this on android, make sure you are using useCallback for the 'renderBackdrop' prop likes the docs say.

lukmccall added a commit to expo/expo that referenced this issue Jan 15, 2024
# Why

Closes [ENG-11073](https://linear.app/expo/issue/ENG-11073)

# How

There is a bug in the Gorhom bottom sheet that causes the backdrop component to flash. It was reported a while ago, but it doesn’t seem to be resolved. Here are related issues: gorhom/react-native-bottom-sheet#208 and gorhom/react-native-bottom-sheet#908.

I've adjusted the animation to mask the disappearing backdrop component. 

# Test Plan

- Expo Go with empty app ✅
brentvatne pushed a commit to expo/expo that referenced this issue Jan 16, 2024
# Why

Closes [ENG-11073](https://linear.app/expo/issue/ENG-11073)

# How

There is a bug in the Gorhom bottom sheet that causes the backdrop component to flash. It was reported a while ago, but it doesn’t seem to be resolved. Here are related issues: gorhom/react-native-bottom-sheet#208 and gorhom/react-native-bottom-sheet#908.

I've adjusted the animation to mask the disappearing backdrop component. 

# Test Plan

- Expo Go with empty app ✅
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working v2 Written in Reanimated v1
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants