React Native app mysteriously freezes after dismissing a modal or action sheet
Asked Answered
K

4

8

I'm experiencing an issue where every time I dismiss a modal, action sheet, or Alert in our React Native app, the app completely freezes and can't be interacted with.

Navigating to a new stack or clicking buttons doesn't repro.

I have to kill the app and restart to interact again. Reloading the app via the packager does not help.

We have code that automatically shows a new modal when one is dismissed and that actually works - the modal is interactable. So it seems that only underlying content is frozen, as if there's still a modal over the top but it's invisible.

The crazy thing is that this is reproing in previous known good branches. So something must have changed with local config/cache, but I can't figure out what. I've re-cloned the repo, cleared the watchman/packager/yarn caches, wiped the simulator of all data. Nothing is fixing the issue.

There are also no logs in the packager, xcode, or Flipper indicating what might be going wrong.

Using react-native-modal, @expo/react-native-action-sheet, and built-in React Native Alert (not using general Expo framework though). I've upgraded these libraries to the latest version.

Running out of ideas. Where else can I look here?


Update: Super-minimal code repros. This modal auto-shows, auto-dismisses, and then the button is unpressable. Removing the modal from the code makes the button pressable.

function TestApp() {
  const [isVisible, setVisible] = useState(true);
  return (
    <>
      <TouchableOpacity style={{ padding: 80 }} delayPressIn={0}>
        <Text>Touch</Text>
      </TouchableOpacity>
      <Modal isVisible={isVisible} onShow={() => setVisible(false)}>
        <Text>Foo</Text>
      </Modal>
    </>
  );
}

The same happens if I add a minimal alert call instead of a modal. In this case I show another alert after 5 seconds which is interactable. Only popovers are interactable - e.g. alerts and modals.

  useEffect(() => Alert.alert("alert"), []);
  useEffect(() => {
    setTimeout(() => Alert.alert("5s alert"), 5000);
  }, []);

Update #2

It looks like each new "popover" style UI makes any previous UI un-interactable.

If I dismiss the first Alert as above, then I can't interact with the underlying TouchableOpacity, but I can interact with the second (5-second) Alert.

However if I do not dismiss the first Alert and the second Alert pops over, I can only dismiss the second alert and not interact with the first alert which remains frozen.

Kacikacie answered 23/7, 2020 at 19:53 Comment(5)
is really difficult to tell without a repro sample, what i have experience with modals in ios is that if you open a modal without completely being sure of the other modal being closed then the app freezes and there is no response, but as i already told you not sure if this could be your case without seeing some code sample.Provisional
Thanks - this was with code already working for a long time, so it's hard to see what could be coded incorrectly. The code was actually working when I came in this morning - I think "restart the computer" probably actually is the fix here, strangely. The app may also not have been picking up changes I was making to debug at the end of the day, like console.logs, which is another clue.Kacikacie
Now reproing again including after a full computer reset and it's picking up changes... going to try and diagnose further.Kacikacie
Your "isVisible" useState logic feels inverted. Going by what you've pasted above, it means that the modal will be shown at first render, and then when it is shown, the onShow function (called after the modal is shown) will attempt to hide it again immediately.Gastrostomy
@Gastrostomy yes, this is just as a test case - I'm seeing what happens when it shows and hides. Same behavior as pressing a button to close it after showing.Kacikacie
S
11

For me the freezing happens only when Flipper layout plugin is active for my app. Disabled the layout plugin, restarted Flipper, restarted my app and the freezing problem was gone.

Savina answered 5/8, 2020 at 13:43 Comment(3)
Holy cow. Thank you, thank you, thank you. That explains why nothing I did in code seemed to affect it, and why it would pop up even in code that was already well-tested and working!Kacikacie
Please note that there is an open issue for this at Flipper, but we still are waiting for someone to create small reproduction project github.com/facebook/flipper/issues/1399#issuecomment-670133415Guardi
Instead of disabling Flipper, this solution is now possible: "in ios/Podfile change use_flipper! to use_flipper!('Flipper' => '0.54.0') and run pod install --repo-update afterwards in ios dir." See: github.com/facebook/flipper/issues/1399#issuecomment-681902393Kacikacie
I
0

Generally Modals are usually accompanied with an overlay layer/background mask. When you dismiss a modal, are you also sure that you are dismissing the overlay layer, because if there is any transparent layer, that can block the touches on other controls.

Ixion answered 29/7, 2020 at 12:31 Comment(1)
Thank you - there shouldn't be any necessary extra work to dismiss the underlying layer. The code here is very simple and just instructs the RN modal to hide, which should take care of "overlay" logic as an implementation detail (it always has before).Kacikacie
G
0

This is caused by an outdated Flipper version being shipped. Replace use_flipper! in the ios/Podfile with use_flipper!('Flipper' => '0.54.0'), and run pod install should fix the issue.

Guardi answered 27/8, 2020 at 11:29 Comment(0)
Z
0

Experienced this. What I found out was that closing the sheet while the render animation is still on causes the sheet overlay to persist in view even after the content has been removed eg. using it for a process feedback & the process executes faster than the sheet render animation.

Solved this temporarily by adding a delay to calls to sheet close to allow enough time for the open animation to complete. eg using the sheet manager. setTimeout(() => SheetManager.hide(sheetId), 2000)

Zoometry answered 1/5, 2024 at 14:37 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.