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

未关闭 适合新手
#3,945 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@huytdps13400 已经在做这个了。

开始于 2026年10月4日。

  • #4013 来自 @omribz156 —— 已关闭,未合并
  • #4045 来自 @huytdps13400 —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
85/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
技术栈
javascript, react-native

调研方向

从 src/commons/asBaseComponent.js 开始,检查 BaseComponent 如何初始化其 colorScheme 状态并注册 appearanceListener。复现 light-to-dark-to-light 切换序列,其中包含在第一次变更后挂载的组件。当受影响的 RNUI 组件能够在两个方向上正确重新渲染,且不会保留过时的颜色时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

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
主要语言
TypeScript
星标
7.2k
派生
749
平均合并
29 分钟
30 天内合并 PR
1

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

wix/react-native-ui-lib 的其他 Issue

查看 wix/react-native-ui-lib 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。