Search code examples
iosreact-nativereact-native-router-flux

react-native ios app doesn't rerender when device is rotated


When I rotate the device the old view rotates but keeps the same dimensions it had, just using part of the screen, until the screen is touched, then it re-renders. (This is in Release mode: in Debugging mode, it does automatically rerender, but only after a delay of a second or two). This happens on the simulator and devices running iOS7 and iOS9.

This problem started after I upgraded my app from react-native 0.24.1 to 0.32.0. This upgrade, of course, like pulling a thread out of a sweater, made it necessary to upgrade lots of 3rd party react-native libraries. In particular, upgrading react-native-router-flux from 3.24.1 to 3.35.0 required a lot of changes in my code.

That said, I can't think of anything I changed that could cause this problem. At first I suspected react-native-orientation, which was particularly tricky to upgrade, so I just removed it entirely from the project, which didn't help.

I added a callback for the onLayout event in my top level view, with a console.log printout. This event evidently does not get triggered after the device is rotated, until the screen is touched. Then the onLayout debugging statement is printed and the react-native code rerenders at the same time.

So it seems that native code is not sending the rotation event across the bridge to javascript code until it can piggyback on some other event.

Any suggestions on how to debug this would be greatly appreciated.

UPDATE: I just remembered the note about flex:1 breaking changes in react-native 0.28. I wonder if this could have something to do with it? They say:

If you previously used flex: 1 where not necessary this change will likely break your layout

The question is, when is it necessary, and how do you know whether it's necessary or not? I can't seem to find documentation on it. I've always used flex:1 everywhere because I found that bad things happen if you don't. In the Scrollview docs the say:

Forgetting to transfer {flex: 1} down the view stack can lead to errors here

Now it seems bad things can happen if you do. Bummer. It seems they actually want you to know what you're doing. What's a hacker to do?

UPDATE 2: That does not appear to be the problem. What a hacker does, of course, is hack. I went through and removed each {flex: 1} one by one starting at the top level. In most cases, it broke the layout and in no case did it fix this problem.


Solution

  • This was apparently a bug in react-native 0.32.0.

    I decided to clean everything and reinstall from npm:

    rm -rf $TMPDIR/react-* && watchman watch-del-all && rm -rf ios/build/ModuleCache/* && rm -rf node_modules/ && npm cache clean && npm i

    When I did it picked up react-native 0.32.1 and the problem went away. 0.32.1 has a commit that seems could be related to this.