66 SubscribeValues ,
77} from '@subscribe-kit/core'
88import { ensureArray , Tuple } from '@subscribe-kit/shared'
9- import { useSyncExternalStore } from 'react'
9+ import { useCallback , useRef , useSyncExternalStore } from 'react'
1010import { useMemoizedEqualValue } from './hooks/useMemoizedEqualValue'
1111
1212export interface CreateWatchOptions < T > {
@@ -24,8 +24,9 @@ export function createWatch<T = any>(options: CreateWatchOptions<T>) {
2424 keyOrKeys ?: K
2525 ) {
2626 const memoizedKey = useMemoizedEqualValue ( keyOrKeys )
27- const value : any = useSyncExternalStore (
28- ( listener ) => {
27+ const pathsValueRef = useRef < any [ ] > ( [ ] )
28+ const subscribe = useCallback (
29+ ( listener : ( ) => void ) => {
2930 const unsubscribe = memoizedKey
3031 ? store . observer . subscribe ( memoizedKey as any , listener , {
3132 immediate : true ,
@@ -35,19 +36,32 @@ export function createWatch<T = any>(options: CreateWatchOptions<T>) {
3536 } )
3637 return unsubscribe
3738 } ,
38- ( ) => {
39- if ( memoizedKey ) {
40- const path = ensureArray ( keyOrKeys ) as PropertyKey [ ] | PropertyKey [ ] [ ]
41- const isPaths = path . some ( ( p ) => Array . isArray ( p ) )
42- if ( isPaths ) {
43- const paths = path . map ( ( p ) => ensureArray ( p ) as PropertyKey [ ] )
44- return paths . map ( ( p ) => getValueByPath ( p , store . values ) )
39+ // eslint-disable-next-line react-hooks/exhaustive-deps
40+ [ memoizedKey , store ]
41+ )
42+ const getSnapshot = useCallback ( ( ) => {
43+ if ( memoizedKey ) {
44+ const path = ensureArray ( memoizedKey ) as PropertyKey [ ] | PropertyKey [ ] [ ]
45+ const isPaths = path . some ( ( p ) => Array . isArray ( p ) )
46+ if ( isPaths ) {
47+ const paths = path . map ( ( p ) => ensureArray ( p ) as PropertyKey [ ] )
48+ const newValue = paths . map ( ( p ) => getValueByPath ( p , store . values ) )
49+ if (
50+ newValue . length !== pathsValueRef . current . length ||
51+ newValue . some (
52+ ( item , index ) => item !== pathsValueRef . current [ index ]
53+ )
54+ ) {
55+ pathsValueRef . current = newValue
4556 }
46- return getValueByPath ( path as PropertyKey [ ] , store . values )
57+ return pathsValueRef . current
4758 }
48- return store . values
59+ return getValueByPath ( path as PropertyKey [ ] , store . values )
4960 }
50- )
61+ return store . values
62+ // eslint-disable-next-line react-hooks/exhaustive-deps
63+ } , [ memoizedKey , store ] )
64+ const value : any = useSyncExternalStore ( subscribe , getSnapshot )
5165 return value
5266 }
5367 return {
0 commit comments