Remove requestAnimationFrame when focusing input on mount (#27217)

Summary:
When using `react-native-screen` which uses native view controller animations for navigation `TextInput` with `autoFocus` causes a weird animation glitch.

Removing the requestAnimationFrame will cause the focus command to be sent in the same batch as starting screen transitions which fixes the issue.

It is unclear why the rAF was added in the first place as it was part of the initial RN open source commit. If someone at facebook has more context that would be great to make sure it doesn't cause unintended side effects.

Credits to kmagiera for figuring out this

## Changelog

[General] [Fixed] - Remove requestAnimationFrame when focusing input on mount
Pull Request resolved: https://github.com/facebook/react-native/pull/27217

Test Plan:
- Tested in an app using react-native-screen to make sure the animation glitch is fixed
- Tested in RNTester to make sure it doesn't cause other issues when not using react-native-screens

Before:

![1](https://user-images.githubusercontent.com/2677334/68799447-2ce5c100-0626-11ea-8310-a9ac9e9419b6.gif)

After:

![2](https://user-images.githubusercontent.com/2677334/68799450-2fe0b180-0626-11ea-865f-ef88f7307831.gif)

Differential Revision: D18666991

Pulled By: TheSavior

fbshipit-source-id: 66664c89e06c9ae65074ddcc4688dc5109fc9c72
This commit is contained in:
Janic Duplessis
2019-11-22 16:13:57 -08:00
committed by Facebook Github Bot
parent d0ed21531a
commit 5798cf2aa9
+14 -3
View File
@@ -702,14 +702,25 @@ function useFocusOnMount(
// Since initialAutoFocusValue and inputRef will never change
// this should match the expected behavior
if (initialAutoFocusValue.current) {
const rafId = requestAnimationFrame(() => {
const focus = () => {
if (inputRef.current != null) {
inputRef.current.focus();
}
});
};
let rafId;
if (Platform.OS === 'android') {
// On Android this needs to be executed in a rAF callback
// otherwise the keyboard opens then closes immediately.
rafId = requestAnimationFrame(focus);
} else {
focus();
}
return () => {
cancelAnimationFrame(rafId);
if (rafId != null) {
cancelAnimationFrame(rafId);
}
};
}
}, [initialAutoFocusValue, inputRef]);