Skip to content

Commit 61ae706

Browse files
committed
migrate: useSyncExternalStore instead of useState at useStore
1 parent 1f70053 commit 61ae706

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

src/core/store.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useState } from 'react';
1+
import { useSyncExternalStore } from 'react';
22
import { DefaultToastOptions, Toast, ToastType } from './types';
33

44
const TOAST_LIMIT = 20;
@@ -157,16 +157,28 @@ export const reducer = (state: State, action: Action): State => {
157157
}
158158
};
159159

160-
const listeners: Array<(state: State) => void> = [];
160+
const store = (() => {
161+
let memoryState: State;
162+
const initialState = (memoryState = { toasts: [], pausedAt: undefined });
163+
const listeners: Set<(state: State) => void> = new Set();
161164

162-
let memoryState: State = { toasts: [], pausedAt: undefined };
165+
const dispatch = (action: Action) => {
166+
memoryState = reducer(memoryState, action);
167+
listeners.forEach((listener) => {
168+
listener(memoryState);
169+
});
170+
};
163171

164-
export const dispatch = (action: Action) => {
165-
memoryState = reducer(memoryState, action);
166-
listeners.forEach((listener) => {
167-
listener(memoryState);
168-
});
169-
};
172+
const getState = () => memoryState;
173+
174+
const subscribe = (listener: () => void) => {
175+
listeners.add(listener);
176+
return () => listeners.delete(listener);
177+
};
178+
const getInitialState = () => initialState;
179+
180+
return { dispatch, getState, subscribe, getInitialState };
181+
})();
170182

171183
export const defaultTimeouts: {
172184
[key in ToastType]: number;
@@ -178,17 +190,14 @@ export const defaultTimeouts: {
178190
custom: 4000,
179191
};
180192

193+
export const dispatch = store.dispatch;
194+
181195
export const useStore = (toastOptions: DefaultToastOptions = {}): State => {
182-
const [state, setState] = useState<State>(memoryState);
183-
useEffect(() => {
184-
listeners.push(setState);
185-
return () => {
186-
const index = listeners.indexOf(setState);
187-
if (index > -1) {
188-
listeners.splice(index, 1);
189-
}
190-
};
191-
}, [state]);
196+
const state = useSyncExternalStore(
197+
store.subscribe,
198+
store.getState,
199+
store.getInitialState
200+
);
192201

193202
const mergedToasts = state.toasts.map((t) => ({
194203
...toastOptions,

0 commit comments

Comments
 (0)