class ToastManager extends EventTarget { get toasts() { return this._toasts // 새로 만들지 않는다 — 같은 참조면 안 바뀐 것 } set toasts(value) { this._toasts = [...value] // 새 참조 = "바뀌었다"는 신호 this.dispatchEvent(new Event('changed')) } // add·remove … 는 전부 이 setter 를 거친다 — 변경과 발행이 한 곳이라 발행 누락이 없다}
const subscribe = (cb) => { toastManager.addEventListener('changed', cb) return () => toastManager.removeEventListener('changed', cb)}// useEffect + useState 로 손으로 복사하던 동기화를 React 가 맡는다.// changed 마다 getSnapshot 을 불러 참조를 비교하고, 다를 때만 리렌더한다.const toasts = useSyncExternalStore(subscribe, () => toastManager.toasts)