question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exception thrown when dismissing a modal on the top of another one

See original GitHub issue

Bug

I cannot close a modal if it is open over another one :

  • When I open the first modal, i can close it properly, everything is fine
  • I open a new modal over that first modal
  • I try to close it and I get one the following error Screenshot 2021-07-20 at 20 26 33

I want the second modal to close properly without throwing an error

Environment info

Library Version
@gorhom/bottom-sheet 3.6.6
react-native 0.64.2
react-native-reanimated 2.1.0
react-native-gesture-handler 1.10.3

I hope some of you can help me, I struggled about this issue for a really long time 😅

Thank you in advance,

Cheers

Steps To Reproduce

  1. Open a modal
  2. Open a new modal within the first one
  3. Close the newly opened modal

Describe what you expected to happen:

  1. I’d like the modal to close without throwing an error

Reproducible sample code

Here is my code :

import {
    BottomSheetBackdrop,
    BottomSheetModal,
} from '@gorhom/bottom-sheet';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { RootState } from '../../store';

import { templates } from './templates/templates.constants';

const Modal = () => {
    const bottomSheetModalRef = useRef<BottomSheetModal[]>([]);
    const modals = useSelector((state: RootState) => state.modals.modals);
    const dispatch = useDispatch();

    useEffect(() => {
        if (modals.length >= 1) {
            bottomSheetModalRef.current[modals.length - 1]?.present();
        }
    }, [modals.length]);

    return modals.map((modal: any, index: number) => {
        const { template, templateProps, modalProps } = modal;
        const Template = templates[template];
        return (
            <BottomSheetModal
                name={index + ''}
                key={index}
                ref={(el) => bottomSheetModalRef.current[index] = el}
                index={1}
                snapPoints={['75%']}
                backdropComponent={BottomSheetBackdrop}
                stackBehavior={'push'}
            >
                <Template
                    {...templateProps}
                    modalProps={modalProps}
                    templateProps={templateProps}
                />
            </BottomSheetModal>
        );
    });
};

export default Modal;

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
pnogiercommented, Jul 22, 2021

Hi guys, I ended up creating a ref for each modal, anyway we will have a maximum of 2 modals stacked at the same time, So I create to refs :

    const modalRef0 = useRef<BottomSheetModal>(null);
    const modalRef1 = useRef<BottomSheetModal>(null);

Then I open them in my useEffect, checking my modals state :

    useEffect(() => {
        if (modals.length === 1) {
            modalRef0?.current?.present();
        } else if (modals.length === 2) {
            modalRef1?.current?.present();
        }
    }, [modals.length]);

Then I use the same condition to close one ref or another.

But when I use my handleCancel :

    const handleCancel = () => {
        Reactotron.log('cancel')
        if (modals.length === 1) {
            modalRef0?.current?.close();
            dispatch(popModal());
        } else if (modals.length === 2) {
            modalRef1?.current?.close();
            dispatch(popModal());
        }
    };

Given as props to my modal template as following :

return modals.map((modal: any, index: number) => {
        const { template, templateProps, modalProps } = modal;
        const Template = templates[template];
        return (
            <BottomSheetModal
                key={index}
                ref={index === 0 ? modalRef0 : index === 1 ? modalRef1 : null}
                index={1}
                snapPoints={[-1, modalProps.height ? modalProps.height : '75%']}
                onDismiss={handleDismiss}
                backdropComponent={BottomSheetBackdrop}
                stackBehavior={'push'}
            >
                <Template
                    {...templateProps}
                    onConfirm={(values) => handleConfirm(modal, values)}
                    onCancel={handleCancel}
                    modalProps={modalProps}
                    templateProps={templateProps}
                />
            </BottomSheetModal>
        );
    });

So, my onDismiss method is the exact same as my cancel method, because I want to pop a modal from my modals redux state when the users dismiss a modal by panning it down. But when I call onCancel, it also triggers my onDismiss.

So I ended up removing my popModal calls in onConfirm and onCancel, so it gets triggered only when dismissing.

This is the workaround I found, not the best, but it’ll work for now I guess,

Thank you guys for your help,

Cheers 🍻

0reactions
pnogiercommented, Jul 22, 2021

@moxspoy thanks for the suggestion, but still doesn’t work…

Read more comments on GitHub >

github_iconTop Results From Across the Web

Problem dismissing multiple modal view controllers
The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in...
Read more >
Exception thrown while executing UI block: *** Collection ...
Description Hey I'm experiencing the weirdest error ever => I'm using Modal component from "react-native" and my app didn't have any issues.
Read more >
Popover API (Explainer) - Open UI
A new content attribute, popover , controls both the top layer status and the dismiss behavior. There are several allowed values for this ......
Read more >
How To Make Modal Windows Better For Everyone
Modals quickly shift visual focus from one part of a website or application to another area of (hopefully related) content. The action is ......
Read more >
Modal | Components - BootstrapVue
Modals are streamlined, but flexible dialog prompts powered by JavaScript and CSS. They support a number of use cases from user notification to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found