colorfy-software / react-native-modalfy

🥞 Modal citizen of React Native.
https://colorfy-software.gitbook.io/react-native-modalfy
MIT License
1.16k stars 48 forks source link

closeModal occasionally stops working, while backdrop press works #98

Closed willadamskeane closed 1 year ago

willadamskeane commented 1 year ago

I'm using Modalfy to manage a stack of modals, and occasionally closeModal will stop working, preventing the current modal from closing. Looking at ModalState, there is a long list of pendingClosingActions that are not resolving. However, pressing the backdrop will successfully close the current modal.

Any help is appreciated!

CharlesMangwa commented 1 year ago

hey @willadamskeane! which version are you using? as well, it would be very helpful if you could provide some reproducible steps in a snack for instance. otherwise, that makes tracking that issue quite tedious.

willadamskeane commented 1 year ago

@CharlesMangwa Still working on getting a reliably reproducing snippet together, but it is definitely happening sporadically to our testers. Is there any reason to expect calling "closeModal(modalName)" wouldn't immediately close that modal? It seems to get caught in some sort of queue, but I can't figure out the conditions that lead to that happening. Feels like a race condition.

Any chance you can think of a way to programmatically "force close" a modal, to circumvent this issue temporarily? Clicking the backdrop always closes the modal, so it seems there is another way to close that doesn't get caught in this queue

willadamskeane commented 1 year ago

@CharlesMangwa Just to give a little more clarity, the issue is occurring reliably if at least one modal is open, and then that modal is closed while another modal is opened simultaneously. After this, closeModal stops working.

Here is a snack that illustrates the issue: https://snack.expo.dev/@willadamskeane/witty-edamame

CharlesMangwa commented 1 year ago

hey @willadamskeane! thanks for the snack! i didn't know this was your (or one of your) use case! what i could suggest, if you want to close a modal and open another one right away (or vice versa), is to use modalfy's calback api instead:

onPress={() => {
-  modalfy().closeModal("ModalA");
-  modalfy().openModal("ModalB");
+ modalfy().closeModal("ModalA", () => modalfy().openModal("ModalB"));
}}

the reason we need to use a callback is mainly due to 1 thing: animations. by using a callback, modalfy is then able to animate the initial modal out, remove it from the stack and only then animate the new modal in (or vice versa). if we don't order things that way, we end up in the race condition you're facing where modalfy is being asked to animate a modal out, remove it from the internal stack, add another modal to the internal stack, animate that other modal in, and all of that pretty much all at once.

of course we also considered using promises but that api turned out to be quite complex to handle especially since modalfy() (which can be used outside of react) exist.

even though this callback api is mentioned in the docs, i realised it wasn't the easiest thing to find if you don't know already what exactly you're looking for. therefore, i've updated the main docs to that effect. hope all of this helps!