Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapping RefreshControl and passing it as JSX does not work on Android #49878

Open
coolsoftwaretyler opened this issue Mar 7, 2025 · 4 comments

Comments

@coolsoftwaretyler
Copy link

coolsoftwaretyler commented Mar 7, 2025

Description

Hey folks, when using the refreshControl as a prop to ScrollView, I'm seeing a slight difference between Android and iOS.

Steps to reproduce

  1. If I directly use the RefreshControl component from React Native as JSX, it works on Android and iOS
  2. If I wrap RefreshControl in a custom component and pass it as JSX, it works on iOS, but Android crashes
  3. If I call my custom component as a function in the prop, it works on both Android and iOS.
import { ScrollView, RefreshControl } from 'react-native'

const CustomRefreshControl = () => {
  const [refreshing, setRefreshing] = useState(false);

  const onRefresh = () => {
    setRefreshing(true);
    setTimeout(() => {
      setRefreshing(false);
    }, 2000);
  };

  return <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />;
};

// This works on Android and iOS
const SomeScreen = () => {
      <ScrollView
        refreshControl={<RefreshControl refreshing={true} onRefresh={() => null} />}

// This works on iOS, not on Android
const SomeScreen = () => {
      <ScrollView
        refreshControl={<CustomRefreshControl />}

// This works on Android and iOS
const SomeScreen = () => {
      <ScrollView
        refreshControl={CustomRefreshControl()}

At first I thought maybe RefreshControl was special and didn't want to be wrapped. Or that the refreshControl prop on ScrollView always wanted to call a function. But the difference cross-platform makes me think that it's a bug somewhere.

Very minor pain point, but I thought I'd capture it in case that's helpful, or perhaps I've misunderstood how it ought to work.

React Native Version

0.78.0

Affected Platforms

Runtime - Android

Output of npx @react-native-community/cli info

System:
  OS: macOS 14.6
  CPU: (16) arm64 Apple M3 Max
  Memory: 224.30 MB / 48.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.18.0
    path: ~/.asdf/installs/nodejs/20.18.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.asdf/installs/nodejs/20.18.0/bin/yarn
  npm:
    version: 11.1.0
    path: ~/.asdf/installs/nodejs/20.18.0/bin/npm
  Watchman:
    version: 2025.02.17.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/tylerwilliams/.asdf/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.0
      - iOS 18.0
      - macOS 15.0
      - tvOS 18.0
      - visionOS 2.0
      - watchOS 11.0
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.21829.142.2421.12409432
  Xcode:
    version: 16.0/16A242d
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.13
    path: /usr/bin/javac
  Ruby:
    version: 3.3.4
    path: /Users/tylerwilliams/.asdf/shims/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.1
    wanted: 15.0.1
  react:
    installed: 19.0.0
    wanted: 19.0.0
  react-native:
    installed: 0.78.0
    wanted: 0.78.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

Stacktrace or Logs

No errors come up in the debug tools from what I can see.

Reproducer

https://github.com/coolsoftwaretyler/RefreshControlReproducer

Screenshots and Videos

Video was too big for GH upload, here's a Dropbox: https://www.dropbox.com/scl/fi/a8106gdwf4st88lsemsuq/2025-03-06-refresher-bug.mov?rlkey=e61k2c5kh3l1ffh8h4k9wes51&st=hdw29mc4&dl=0

@cipolleschi
Copy link
Contributor

@coolsoftwaretyler thanks for opening the issue! We will look into it.

Given you tested on 0.78, I assume this is what you observe in the New Architecture, am I right? Have you perhaps checked also the old architecture to see how it behaved?

@coolsoftwaretyler
Copy link
Author

Yes, so far I've only checked on new arch. I ran into this originally on an Expo SDK 52 app, so it seems to also happen back to v0.76 (also on new arch). For the reproducer I wanted to see if it was an issue on latest.

I'll check the old arch and report back.

@coolsoftwaretyler
Copy link
Author

Looks to be an issue on the old architecture on React Native 0.78.0 as well:

https://www.dropbox.com/scl/fi/4farmhgcan2qds2yi7h8r/2025-03-07-refresher-bug-old-arch.mov?rlkey=gkydpdqpndzy47j5eboktsda7&st=5qr9icir&dl=0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants