Recently at work, I encounter a weird animation glitch bug while navigate to a new page with keyboard focus. At first I thought it was cause by the logic of navigation, but later on it turn outs to be
With some digging, I find out it was cause by using
autoFocus. And there's already a PR fixing it, thanks to @janicduplessis 's contribution. In summary,
requestAnimationFrame causes the focus command to be sent in the same batch as starting screen transitions.
More in @janicduplessis point of view
Looking at the iOS code I don't see how a race could happen since it calls UIManager.focus which then uses addUIBlock to focus the input. All the operation should happen in order so the new input will always be created and attached before focus is called. On android it uses dispatchViewManagerCommand which uses UIViewOperationQueue so it will also be properly synced with view creating operations.
Might have been a workaround for an old race condition bug that was since then fixed.
It seems like a bug with UIKit, It must assume keyboard focus will happen in the same event loop as the transition. Normally you'd call becomeFirstResponder in viewWillAppear. This will cause the keyboard to slide in from right to left smoothly with the new screen animation. When removing the raF it will cause pretty much the same thing to happen.
Just tested on Android and it causes the keyboard to open then close immediately :( This explains why this was added.
How to fix it?
This really depends on which RN version you're in. If you're using
v0.62.0-rc.0, then good news is it's already fixed.
But to upgrade to the latest RN version isn't that easy, so my suggestion is to do the
autoFocus manually. By calling
focus() manually in
componentdidmount and set some delay with
setTimeout() should do the trick.
In the recent commit of RN, JS implementation on
autoFocus has been removed. We no longer need to call focus on mount from JS as both iOS and Android implements it natively now.