react / react/react-native

Starting from 0.64.0 `RefreshControl` causes an unwanted visual jump in the list content when the `refreshing` prop goes from `true` to `false`

Open
#31,461 39 comments 33 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Accessibility Accessibility Team - Evaluated Component: RefreshControl Help Wanted :octocat: Impact: Regression Platform: iOS
Dominant language
C++
Stars
127k
Forks
25.3k
Avg merge
1d 23h
Merged PRs (30d)
4

Description

Description

Starting from 0.64.0 in iOS on a physical device: When using <RefreshControl> inside <ScrollView> or <FlatList>, the content in the list has an unwanted visual jump down when the refreshing prop goes from true to false - this is not the case in 0.63.4.

https://user-images.githubusercontent.com/1485576/116700722-626f9d00-a9c7-11eb-8ce9-107bf3dca592.mov

React Native version:

System:
    OS: macOS 11.2
    CPU: (8) x64 Apple M1
    Memory: 667.83 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.15.4 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.10 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK:
      API Levels: 28, 29, 30
      Build Tools: 28.0.3, 29.0.2, 30.0.3
      System Images: android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7042882
    Xcode: 12.4/12D4e - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_282 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1 
    react-native: 0.64.0 => 0.64.0 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Install a clean version of 0.64.0 and run the code from the RefreshControl docs https://reactnative.dev/docs/refreshcontrol on a physical device. In the provided videos I have only changed the fake timeout from 2000ms -> 500ms to show the jumping quicker and printed the refreshing state.

Expected Results

This is how it looks in 0.63.4, where no jumping is happening:

https://user-images.githubusercontent.com/1485576/116701050-c1351680-a9c7-11eb-8507-cbc0e8eab36b.mov

Snack, code example, screenshot, or link to a repository:

import React from 'react';
import { RefreshControl, SafeAreaView, ScrollView, StyleSheet, Text } from 'react-native';

const wait = (timeout) => {
  return new Promise(resolve => setTimeout(resolve, timeout));
}

const App = () => {
  const [refreshing, setRefreshing] = React.useState(false);

  const onRefresh = React.useCallback(() => {
    setRefreshing(true);
    wait(500).then(() => setRefreshing(false));
  }, []);

  return (
    <SafeAreaView style={styles.container}>
      <ScrollView
        contentContainerStyle={styles.scrollView}
        refreshControl={
          <RefreshControl
            refreshing={refreshing}
            onRefresh={onRefresh}
          />
        }
      >
        <Text>{refreshing ? 'Refreshing' : 'Done'}</Text>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  scrollView: {
    flex: 1,
    backgroundColor: 'pink',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the RefreshControl documentation example and reproduce the transition from refreshing=true to false on a physical iOS device using React Native 0.64.0, then compare it with 0.63.4. Trace the RefreshControl behavior used by ScrollView and FlatList, and consider the issue done when the content no longer jumps after refreshing ends.

Written by the indexing model from the issue text.

Assessment

Tech stack
react-native
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
50/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.