在主题属性更改或卸载时,烤面包机会泄露 matchMedia 变化监听器
作者: MILLERMARRU创建于 2026年8月15日更新于 2026年8月15日
在 src/index.tsx 中,将 theme="system" 与 prefers-color-scheme 同步的效果永远不会清理其监听器:
const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
try {
darkMediaQuery.addEventListener('change', ({ matches }) => {
if (matches) setActualTheme('dark');
else setActualTheme('light');
});
} catch (error) {
darkMediaQuery.addListener(({ matches }) => { ... });
}该效果的依赖数组为 [theme],因此每次 theme 更改时,都会通过 window.matchMedia(...) 创建一个新的 MediaQueryList 对象,并将新的监听器添加到该对象中,但没有任何内容删除之前的监听器,也没有任何内容在卸载时删除它们。在将 theme 绑定到一个实时切换元素()的应用程序中,每次更改主题时,都会在页面的整个生命周期中创建一个新的泄露闭包对 setActualTheme。
内容来源: emilkowalski/sonner