[0.64.0-rc.1] - KeyboardAvoidingView freezes ios app when wrapped around a scrollview
See original GitHub issueDescription
When a KeyboardAvoidingView is wrapped around a ScrollView with behavior="height"
and the scrollview has contents that has a scrollable height > device height, focussing a text input will freeze app on ios, I cannot test on android at the moment so can only confirm the issue on iOS.
React Native version:
System:
OS: macOS 11.0.1
CPU: (8) x64 VirtualApple @ 2.50GHz processor
Memory: 119.02 MB / 16.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.15.1 - /var/folders/wr/9smsws7s7fz53bs2905q080h0000gn/T/yarn--1606680389084-0.9742257659131075/node
Yarn: 1.22.10 - /var/folders/wr/9smsws7s7fz53bs2905q080h0000gn/T/yarn--1606680389084-0.9742257659131075/yarn
npm: 6.14.8 - ~/.nvm/versions/node/v14.15.1/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.10.0 - /Users/oliverwinter/.rvm/gems/ruby-2.6.1/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 14.2, DriverKit 20.0, macOS 11.0, tvOS 14.2, watchOS 7.1
Android SDK:
API Levels: 29, 30
Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2
System Images: android-30 | Google APIs Intel x86 Atom
Android NDK: Not Found
IDEs:
Android Studio: 4.1 AI-201.8743.12.41.6953283
Xcode: 12.2/12B45b - /usr/bin/xcodebuild
Languages:
Java: 1.8.0_275 - /usr/bin/javac
Python: 2.7.16 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.1 => 17.0.1
react-native: 0.64.0-rc.0 => 0.64.0-rc.0
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Steps To Reproduce
The following snippet can be used to replicate the issue.
import React from 'react';
import {
KeyboardAvoidingView,
SafeAreaView,
ScrollView,
TextInput,
View,
} from 'react-native';
const App = () => {
return (
<SafeAreaView>
<KeyboardAvoidingView behavior="height">
<ScrollView>
<TextInput
placeholder="Placeholder text"
style={{height: 50, fontSize: 20}}
/>
<View style={{height: 2000, backgroundColor: 'red'}} />
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
);
};
export default App;
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:12 (7 by maintainers)
Top Results From Across the Web
React Native KeyboardAvoidingView is not working as expected
The screen is Wrapped inside KeyboardAvoidingView and ScrollView components ...
Read more >@react-native/eslint-plugin-specs | Yarn - Package Manager
React Native brings React's declarative UI framework to iOS and Android. With React Native, you use native UI controls and have full access...
Read more >react-native/CHANGELOG.md - UNPKG
This change enforces Node >= 14 for React Native builds. 30, - Bump Android Gradle Plugin to 7.0.1. ([272cfe5d13](https ...
Read more >keyboardavoidingview modal | The search engine you control.
safeAreaView}> <View style={styles.modalContentContainer}> <Button title={"Close Modal"} onPress={() => setModalVisible(false)}/> <ScrollView> <View style={ ...
Read more >Last issues related to facebook/react-native project - PullAnswer
React native screen and react safe area view is crashing , my react ... IOS KeyboardAvoidingView automatically closes Keyboard when clicking on TextInput....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
What’s confusing me about b08fff6f869e00c20c0dcdf7aca71284c2f276f0 is this line:
From my experimenting, the order of these events in React Native 0.63 is:
onLayout
is triggered, before anyTextInput
is pressedTextInput
is pressed a keyboard event is triggered. This keyboard event results in asetState
callsetState
call results in a re-render ofKeyboardAvoidingView
, which results inonLayout
being called again(The issue we’re seeing both here and in #30532 comes from the fact that there is now a
setState
call inonLayout
, which triggers another layout, which triggers anothersetState
, etc.)But back to this quote:
My main question here is: after the first layout, assuming the parent component doesn’t rerender, shouldn’t a keyboard event always precede the
onLayout
? In what circumstances does aonLayout
precede a keyboard event? TheonLayout
can’t happen before thesetState
, right? If anonLayout
occurs without a preceding keyboard event, can’t we conclude that it has nothing to do with the keyboard, and instead must be in response to a parent component resizing?If b08fff6f869e00c20c0dcdf7aca71284c2f276f0 was indeed related to parent components resizing, I think I might have a solution.
I have a customized
KeyboardAvoidingView
in my project that has to deal with the edge case of a parent component resizing. We need to be able to differentiate between anonLayout
that occurs in response to our ownsetState
(in which case we should not change our calculations), and anonLayout
that occurs in response to a parent resize (in which case the calculations need to be updated). The way we handle this is simply to ignore allonLayout
calls that occurs while the keyboard is up (eg. after a “keyboard show” event occurs, but before a “keyboard hide” event occurs).I think that sort of approach would work here, but it’s hard to say without understanding the issue that b08fff6f869e00c20c0dcdf7aca71284c2f276f0 is addressing better.
@alloy the issue was introduced in this commit https://github.com/facebook/react-native/commit/b08fff6f869e00c20c0dcdf7aca71284c2f276f0,
The issue is that onLayout event is fired multiple times and the
layout.y
value for the native event is different each time, which then flows into the setState for height getting updated multiple times, with different values, which then trigger the onLayout again… infinite loop.So the issue seems to stem from the onLayout events, and I am not sure if we can revert this commit in 64 due to the
Fabric has different order of events
comment in the commit message.