useColorScheme 在每次渲染时都会重新订阅; 在调度过程中移除的监听器会错过 prefer-color-scheme 更改

作者: re5et创建于 2026年8月3日更新于 2026年8月30日

** react-native-web 版本:** 0.21.2 (自钩子引入后出现bug)

□ 总结

`使用ColorScheme'的订阅效果没有依赖数组:

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你来干什么? //出/出/出/使用ColorScheme/index.js react.useeffect (( ()) {{{{} 函数倾听器( 出现) { colorScheme(出现.colorScheme); {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? var Appearance$addChange = 外观.addChange listener(听众),, 删除 = Appearance$addChange.remove; 页面存档备份,存于互联网档案馆. 返回删除; }; // QQ没有 Dep 阵列: 泪下 + 在 Every 渲染上重新添加收听器


由于收听器被移除并被再加到每个渲染物上,一个"偏好色-相色-相色"的改变可以永久地钩住实例:

1. MediaQueryList将更改发送到其听众列表.
2. 组件中的第一个 " 使用ColorScheme " 实例接收并设定了国家;组件重新交付。
3. 重新投放器对组件的****其他**`使用ColorScheme ' 实例进行无滴效应清理,删除其听众**中发**。
4. 根据DOM语义,在发送过程中删除的听众从未收到飞行中的事件——因此,这些实例将 stale 方案保留到*next * 变化(然后将一个不同的子集拖出).

任何成分(或钩状成分)如果最终在其成像树中有一个以上的 " 使用ColorScheme " 实例,就会击中这一点。 在我们的应用软件(Surf,一个大型的RN-web产品)中,将OS主题拼接在上一个调色板上留下了大而不同的页面部分,直到重新装入,其方式看起来是随机的,因为它依赖于听众的注册命令.

□ 经验确认

我们通过 Playwright 的 “page.emulate Media” 的“window.match Media”(计算注册量和每个听众的发送量)和驱动“ prefers-color-scheme”翻转:

- ** 未分发:** 在MediaQueryList上注册的39名听众;只有**11人向一个翻转点开火**(步入模式——正是第一位被发射的听众被跳过的部分的兄弟级事例);46次中途撤离。 探测组件“使用ColorScheme()”两次同时显示“暗相”和“光相”。
- ** 固定如下:** **39/39发射**,零中发,每个消费者更新。

□ 修补

添加缺失的依赖性数组, 以便订阅幸存到重发( 收听器关闭只抓取稳定的“ setColorScheme ” ):

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你来干什么?
var Appearance$addChange = 外观.addChange listener(听众),,
删除 =   Appearance$addChange.remove; 页面存档备份,存于互联网档案馆.
返回删除;
- ;
+}, [ ] ;

我们正通过补丁包运送这个 完全解决了这个问题 如果有用,很高兴打开公关

Claude(大赦国际)起草

内容来源: necolas/react-native-web