Skip to content

[Fabric][iOS] RefreshControl tintColor/title props not applied on initial mount #56343

@mikaelkristiansson

Description

@mikaelkristiansson

Description

Description

On iOS with Fabric (New Architecture) enabled, RefreshControl props like tintColor, title, and titleColor are not applied on initial mount. This causes the refresh spinner to be invisible against dark backgrounds (e.g., dark mode).

Root Cause

In RCTPullToRefreshViewComponentView.mm, the updateProps:oldProps: method uses *_props instead of *oldProps when constructing oldConcreteProps:

// Line 79 — current (buggy)
const auto &oldConcreteProps = static_cast<const PullToRefreshViewProps &>(*_props);

Before the initial layout, updateProps stores incoming props into _props and returns early (lines 74–76). Then layoutSubviews replays the update:

[self updateProps:_props oldProps:PullToRefreshViewShadowNode::defaultSharedProps()];
Here, _props (new) and oldProps (default) are different objects, so the comparison should detect changes. However, because line 79 reads from *_props instead of *oldProps, oldConcreteProps and newConcreteProps both resolve to the same stored _props object. All comparisons evaluate to equal, so no props are applied to _refreshControl.

Fix

Change line 79 to use the oldProps parameter:

// Fixed
const auto &oldConcreteProps = static_cast<const PullToRefreshViewProps &>(*oldProps);

Expected Behavior

The refresh spinner should use the specified tintColor on initial mount.

Actual Behavior

The tintColor prop is silently ignored on initial mount. The UIRefreshControl retains its default appearance.

React Native Version

0.81.5 (confirmed present, but likely affects all Fabric-enabled versions since the deferred-props logic was introduced)

Affected Platforms

iOS (Fabric only)

Steps to reproduce

  1. Enable New Architecture (Fabric) in an iOS app
  2. Use a dark background (e.g., dark mode)
  3. Add a RefreshControl with tintColor set to a light color (e.g., #ffffff)
  4. Pull to refresh — the spinner is invisible because it uses the default color (dark) instead of the specified tintColor

React Native Version

0.81.5

Affected Platforms

Runtime - iOS

Areas

Fabric - The New Renderer

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

System:
  OS: macOS 26.4
  CPU: (11) arm64 Apple M3 Pro
  Memory: 1.53 GB / 36.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.19.5
  Yarn:
    version: 1.22.22
  npm:
    version: 10.8.2
  Watchman:
    version: 2026.03.16.00
Managers:
  CocoaPods:
    version: 1.16.2
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.2
      - iOS 26.2
      - macOS 26.2
      - tvOS 26.2
      - visionOS 26.2
      - watchOS 26.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2025.3 AI-253.30387.90.2532.14935130
  Xcode:
    version: 26.3/17C529
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.16
  Ruby:
    version: 3.4.3
npmPackages:
  "@react-native-community/cli":
    installed: 20.1.1
    wanted: 20.1.1
  react:
    installed: 19.1.0
    wanted: 19.1.0
  react-native:
    installed: 0.81.5
    wanted: 0.81.5
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true

info React Native v0.84.1 is now available (your project is running on v0.81.5).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.84.1
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.81.5&to=0.84.1
info For more info, check out "https://reactnative.dev/docs/upgrading?os=macos".

Stacktrace or Logs

no stacktrace or logs

MANDATORY Reproducer

https://github.com/mikaelkristiansson/RefreshControlBug

Screenshots and Videos

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions