Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Vertical scrollbar never reappears after resizing window from non-scrollable back to scrollable (ScrollBarComponent::updateVisibility latch)

Aperta
#16,251 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Tranquilla
Stack tecnologico
cpp, react-native
Ambito
desktop, frontend

Direzione di ricerca

Inizia in Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp, in corrispondenza di ScrollBarComponent::updateVisibility, quindi segui ContentSize, updateLayoutMetrics e updateShowsVerticalScrollIndicator. Riproduci la sequenza di ridimensionamento con l’esempio minimo di ScrollView e separa lo stato della prop dell’indicatore dalla visibilità calcolata; il lavoro è completato quando entrambe le barre, verticale e orizzontale, ricompaiono quando il contenuto torna a essere più grande del viewport.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug Needs: Triage :mag:
Problem Description

Problem Description

A ScrollView's vertical scrollbar gets permanently latched hidden once the content has fit the viewport, and never comes back even when a later resize makes the content scrollable again.

Sequence:

  1. Content is larger than the viewport → scrollbar shows (on hover). ✅
  2. Enlarge the window until the content fits the viewport → scrollbar correctly disappears. ✅
  3. Shrink the window again so the content is larger than the viewport → scrollbar does not come back. ❌ (mouse-wheel scrolling still works)

Once the bar has been hidden because the content fit the viewport, no later resize shows it again. The only way to recover is to change the showsVerticalScrollIndicator prop.

Root cause

Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp, ScrollBarComponent::updateVisibility (line numbers from the 0.82.5 shipped source):

void updateVisibility(bool visible) noexcept {
  if ((m_size.Width <= 0.0f && m_size.Height <= 0.0f) ||
      (m_contentSize.Width <= 0.0f && m_contentSize.Height <= 0.0f)) {
    m_rootVisual.IsVisible(false);
    return;
  }

  if (!visible) {                 // (A)
    m_visible = false;
    m_rootVisual.IsVisible(visible);
    return;                       // early-return: content/size are NOT re-evaluated
  }

  bool newVisibility = false;     // (B) recompute only when visible == true
  if (m_vertical) {
    newVisibility = (m_contentSize.Height > m_size.Height);
  } else {
    newVisibility = (m_contentSize.Width > m_size.Width);
  }

  m_visible = newVisibility;
  m_rootVisual.IsVisible(m_visible);
}

The size/content-driven callers pass the previously computed state back in as the visible argument:

// ContentSize(...)         -> updateVisibility(m_visible);
// updateLayoutMetrics(...) -> updateVisibility(m_visible);

m_visible defaults to true, and updateShowsVerticalScrollIndicator(value) calls updateVisibility(true|false) from the prop. So m_visible conflates two concepts: the prop showsVerticalScrollIndicator and the computed result (content > viewport).

When the window is enlarged so content fits, branch (B) sets m_visible = false. From then on, every layout/content update calls updateVisibility(m_visible == false), which hits branch (A) and early-returns without re-evaluating content > viewport — so shrinking the window back never re-enables the bar.

Proposed fix

Track the prop separately from the computed visibility and always recompute on size/content changes:

bool m_indicatorEnabled{true};   // set from showsVerticalScrollIndicator
bool m_visible{true};            // computed: (content > viewport) && enabled

void updateVisibility() noexcept {
  if ((m_size.Width <= 0.0f && m_size.Height <= 0.0f) ||
      (m_contentSize.Width <= 0.0f && m_contentSize.Height <= 0.0f)) {
    m_rootVisual.IsVisible(false);
    return;
  }
  const bool scrollable = m_vertical
      ? (m_contentSize.Height > m_size.Height)
      : (m_contentSize.Width > m_size.Width);
  m_visible = m_indicatorEnabled && scrollable;
  m_rootVisual.IsVisible(m_visible);
}
  • updateShowsVerticalScrollIndicator(value) → m_indicatorEnabled = value; updateVisibility();
  • ContentSize(...) / updateLayoutMetrics(...) → updateVisibility();

The same applies to the horizontal scrollbar.

Workaround (for app authors)

Toggle showsVerticalScrollIndicator for one frame on every viewport size change, which forces updateShowsVerticalScrollIndicator(true) → updateVisibility(true) to recompute:

const [showVScroll, setShowVScroll] = useState(true);
const onLayout = useCallback(() => {
  setShowVScroll(false);
  requestAnimationFrame(() => setShowVScroll(true));
}, []);
// <ScrollView showsVerticalScrollIndicator={showVScroll} onLayout={onLayout} />
Steps To Reproduce
  1. Create/run a Composition (Fabric) RNW 0.82 app whose root renders a vertically scrollable ScrollView:
    import { ScrollView, Text } from 'react-native';
    
    export default function App() {
      return (
        <ScrollView showsVerticalScrollIndicator>
          {Array.from({ length: 60 }).map((_, i) => (
            <Text key={i} style={{ height: 40 }}>{`row ${i}`}</Text>
          ))}
        </ScrollView>
      );
    }
    
  2. Launch in a small window → vertical scrollbar appears on hover.
  3. Enlarge / maximize the window until all rows fit → scrollbar disappears (correct).
  4. Shrink / restore the window so the rows no longer fit → scrollbar stays hidden, even though the view is scrollable (mouse wheel still scrolls).
Expected Results

After step 4, the vertical scrollbar should be available again (on hover) because the content is once more larger than the viewport.

CLI version

20.0.0

Environment
System:
  OS: Windows 11
SDKs:
  Windows SDK:
    AllowDevelopmentWithoutDevLicense: Enabled
    Versions:
      - 10.0.22621.0
      - 10.0.26100.0
IDEs:
  Visual Studio:
    - 18.7.11903.348 (Visual Studio Community 2026)
npmPackages:
  "@react-native-community/cli":
    installed: 20.0.0
    wanted: 20.0.0
  react:
    installed: 19.1.1
    wanted: 19.1.1
  react-native:
    installed: 0.82.1
    wanted: 0.82.1
  react-native-windows:
    installed: 0.82.5
    wanted: 0.82.5
Community Modules

From dependencies in package.json:

@expo/react-native-action-sheet: ^4.1.1
@fluentui/react-native: ^0.43.1
@react-native/new-app-screen: 0.82.1
@react-navigation/native: ^7.2.2
@react-navigation/stack: ^7.4.2
@reduxjs/toolkit: ^2.3.0
axios: ^1.9.0
i18next: ^24.2.3
react-i18next: ^15.4.1
react-native-popup-menu: ^0.17.0
react-native-safe-area-context: ^5.5.2
react-native-svg: ^15.12.1
react-redux: ^9.2.0
redux-thunk: ^3.1.0

Note: the bug reproduces with a bare ScrollView and does not depend on any of these modules.

Target React Native Architecture

New Architecture (WinAppSDK) Only

Target Platform Version

10.0.22621

Visual Studio Version

Visual Studio 2026

Build Configuration

Debug

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

Minimal repro is the ScrollView snippet under Steps To Reproduce (no community modules required). Repro is a window-resize interaction (enlarge until content fits, then shrink), so it is not reproducible in a Snack — it requires a desktop RNW window.

Lingua principale
C++
Stelle
17.4k
Fork
1.2k
Merge medio
2g 17h
PR unite (30g)
13

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/react-native-windows

Tutte le issue di microsoft/react-native-windows

Issue simili

Altre issue su C++

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.