asBaseComponent: stale module-level colorScheme prevents re-render on scheme switch back

Abierto Apto para principiantes
#3,945 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@huytdps13400 ya está trabajando en esto.

Desde el 4/10/2026.

  • #4013 de @omribz156 — cerrado sin fusionar
  • #4045 de @huytdps13400 — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
85/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
javascript, react-native

Línea de trabajo

Empieza en src/commons/asBaseComponent.js e inspecciona cómo BaseComponent inicializa su estado colorScheme y registra appearanceListener. Reproduce la secuencia de cambio light-to-dark-to-light con componentes montados después del primer cambio. Se considera terminado cuando los componentes RNUI afectados se vuelven a renderizar correctamente en ambas direcciones sin conservar colores obsoletos.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug

Description

asBaseComponent HOC captures colorScheme as a module-level constant at import time. Since BaseComponent extends React.PureComponent (via UIComponent), components mounted after a scheme change hold a stale state.colorScheme that matches the original scheme. When switching back to that original scheme, the appearanceListener guard (this.state.colorScheme !== colorScheme) evaluates to false, skipping setState and preventing re-render.

Related to
  • Components
  • Demo
  • Docs
  • Typings
Steps to reproduce
  1. App starts in light mode → module-level colorScheme is captured as 'light'
  2. Go to a settings/appearance screen and switch to dark mode → all RNUI components re-render correctly
  3. Navigate to any screen — new components mount during dark mode with state.colorScheme = 'light' (stale module-level value)
  4. Switch back to light mode → Scheme.broadcastSchemeChange('light') fires
  5. Stale components check 'light' !== 'light' → false → setState is never called → no re-render
Expected behavior

All RNUI components (Text, View, Button, Switch, etc.) should re-render with the updated color scheme when switching in both directions (light → dark AND dark → light).

Actual behavior

Components mounted after the first scheme change do not re-render when switching back to the original scheme. They retain the previous scheme's colors (e.g., light gray text on a light background) because BaseComponent (a PureComponent) skips rendering — both props and state appear unchanged.

More Info

Code snippet

The bug is in src/commons/asBaseComponent.js:

// Line 8 — evaluated ONCE at module load, never updated
const colorScheme = Scheme.getSchemeType();

function asBaseComponent(WrappedComponent, options = {}) {
  // BaseComponent extends UIComponent which extends React.PureComponent
  class BaseComponent extends UIComponent {
    state = {
      error: false,
      colorScheme  // All instances get the stale module-level value
    };

    appearanceListener = colorScheme => {
      // This guard fails for stale instances when switching back to the original scheme
      if (this.state.colorScheme !== colorScheme) {
        this.setState({ colorScheme });
      }
    };
  }
}

Fix — evaluate Scheme.getSchemeType() per instance instead of once at module level:

 const EMPTY_MODIFIERS = {};
-const colorScheme = Scheme.getSchemeType();
 function asBaseComponent(WrappedComponent, options = {}) {
   class BaseComponent extends UIComponent {
     state = {
       error: false,
-      colorScheme
+      colorScheme: Scheme.getSchemeType()
     };
Screenshots/Video

N/A — the visual symptom is dark-theme text colors (e.g., #C9D6DF) rendered on a light-theme background (#F0F5F9), causing text to blend/disappear.

Environment
  • React Native version: 0.83
  • React Native UI Lib version: 8.3.4
Affected platforms
  • Android
  • iOS
  • Web
Lenguaje dominante
TypeScript
Estrellas
7.2k
Forks
749
Merge medio
29 min
PR fusionados (30 d)
1

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de wix/react-native-ui-lib

Todos los issues de wix/react-native-ui-lib

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.