#782·sonner

在主题属性更改或卸载时,烤面包机会泄露 matchMedia 变化监听器

作者: MILLERMARRU创建于 2026年8月15日更新于 2026年8月15日

src/index.tsx 中,将 theme="system"prefers-color-scheme 同步的效果永远不会清理其监听器:

javascript
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