question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[0.64.0-rc.1] - KeyboardAvoidingView freezes ios app when wrapped around a scrollview

See original GitHub issue

Description

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:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
Ashoatcommented, Dec 10, 2020

What’s confusing me about b08fff6f869e00c20c0dcdf7aca71284c2f276f0 is this line:

In Fabric, keyboardWillChangeFrame event is fired before onLayout, but in Paper it is the other way around.

From my experimenting, the order of these events in React Native 0.63 is:

  1. First onLayout is triggered, before any TextInput is pressed
  2. After the TextInput is pressed a keyboard event is triggered. This keyboard event results in a setState call
  3. The setState call results in a re-render of KeyboardAvoidingView, which results in onLayout being called again

(The issue we’re seeing both here and in #30532 comes from the fact that there is now a setState call in onLayout, which triggers another layout, which triggers another setState, etc.)

But back to this quote:

In Fabric, keyboardWillChangeFrame event is fired before onLayout, but in Paper it is the other way around.

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 a onLayout precede a keyboard event? The onLayout can’t happen before the setState, right? If an onLayout 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 an onLayout that occurs in response to our own setState (in which case we should not change our calculations), and an onLayout 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 all onLayout 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.

2reactions
owinter86commented, Dec 7, 2020

@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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found