@@ -1787,7 +1787,7 @@ function mountSyncExternalStore<T>(
17871787 return nextSnapshot;
17881788}
17891789
1790- function rerenderSyncExternalStore < T > (
1790+ function updateSyncExternalStore < T > (
17911791 subscribe: (() => void ) => ( ) => void ,
17921792 getSnapshot : ( ) => T ,
17931793 getServerSnapshot ?: ( ) => T ,
@@ -1822,83 +1822,7 @@ function rerenderSyncExternalStore<T>(
18221822 }
18231823 }
18241824 }
1825- let snapshotChanged = true ;
1826- if ( currentHook !== null ) {
1827- const prevSnapshot = currentHook . memoizedState ;
1828- snapshotChanged = ! is ( prevSnapshot , nextSnapshot ) ;
1829- if ( snapshotChanged ) {
1830- hook . memoizedState = nextSnapshot ;
1831- markWorkInProgressReceivedUpdate ( ) ;
1832- }
1833- }
1834- const inst = hook . queue ;
1835-
1836- updateEffect ( subscribeToStore . bind ( null , fiber , inst , subscribe ) , [
1837- subscribe ,
1838- ] ) ;
1839-
1840- // Whenever getSnapshot or subscribe changes, we need to check in the
1841- // commit phase if there was an interleaved mutation. In concurrent mode
1842- // this can happen all the time, but even in synchronous mode, an earlier
1843- // effect may have mutated the store.
1844- if (
1845- inst . getSnapshot !== getSnapshot ||
1846- snapshotChanged ||
1847- // Check if the subscribe function changed. We can save some memory by
1848- // checking whether we scheduled a subscription effect above.
1849- ( workInProgressHook !== null &&
1850- workInProgressHook . memoizedState . tag & HookHasEffect )
1851- ) {
1852- fiber . flags |= PassiveEffect ;
1853- pushEffect (
1854- HookHasEffect | HookPassive ,
1855- updateStoreInstance . bind ( null , fiber , inst , nextSnapshot , getSnapshot ) ,
1856- createEffectInstance ( ) ,
1857- null ,
1858- ) ;
1859-
1860- // Unless we're rendering a blocking lane, schedule a consistency check.
1861- // Right before committing, we will walk the tree and check if any of the
1862- // stores were mutated.
1863- const root : FiberRoot | null = getWorkInProgressRoot ( ) ;
1864-
1865- if ( root === null ) {
1866- throw new Error (
1867- 'Expected a work-in-progress root. This is a bug in React. Please file an issue.' ,
1868- ) ;
1869- }
1870-
1871- if ( ! isHydrating && ! includesBlockingLane ( root , renderLanes ) ) {
1872- pushStoreConsistencyCheck ( fiber , getSnapshot , nextSnapshot ) ;
1873- }
1874- }
1875-
1876- return nextSnapshot;
1877- }
1878-
1879- function updateSyncExternalStore < T > (
1880- subscribe: (() => void ) => ( ) => void ,
1881- getSnapshot : ( ) => T ,
1882- getServerSnapshot ?: ( ) => T ,
1883- ) : T {
1884- const fiber = currentlyRenderingFiber ;
1885- const hook = updateWorkInProgressHook ( ) ;
1886- // Read the current snapshot from the store on every render. This breaks the
1887- // normal rules of React, and only works because store updates are
1888- // always synchronous.
1889- const nextSnapshot = getSnapshot ( ) ;
1890- if ( __DEV__ ) {
1891- if ( ! didWarnUncachedGetSnapshot ) {
1892- const cachedSnapshot = getSnapshot ( ) ;
1893- if ( ! is ( nextSnapshot , cachedSnapshot ) ) {
1894- console . error (
1895- 'The result of getSnapshot should be cached to avoid an infinite loop' ,
1896- ) ;
1897- didWarnUncachedGetSnapshot = true ;
1898- }
1899- }
1900- }
1901- const prevSnapshot = ( ( currentHook : any ) : Hook ) . memoizedState ;
1825+ const prevSnapshot = ( currentHook || hook ) . memoizedState ;
19021826 const snapshotChanged = ! is ( prevSnapshot , nextSnapshot ) ;
19031827 if ( snapshotChanged ) {
19041828 hook . memoizedState = nextSnapshot ;
@@ -1941,7 +1865,7 @@ function updateSyncExternalStore<T>(
19411865 ) ;
19421866 }
19431867
1944- if ( ! includesBlockingLane ( root , renderLanes ) ) {
1868+ if ( ! isHydrating && ! includesBlockingLane ( root , renderLanes ) ) {
19451869 pushStoreConsistencyCheck ( fiber , getSnapshot , nextSnapshot ) ;
19461870 }
19471871 }
@@ -3392,7 +3316,7 @@ const HooksDispatcherOnRerender: Dispatcher = {
33923316 useDeferredValue : rerenderDeferredValue ,
33933317 useTransition : rerenderTransition ,
33943318 useMutableSource : updateMutableSource ,
3395- useSyncExternalStore : rerenderSyncExternalStore ,
3319+ useSyncExternalStore : updateSyncExternalStore ,
33963320 useId : updateId ,
33973321} ;
33983322if (enableCache) {
@@ -4079,11 +4003,7 @@ if (__DEV__) {
40794003 ) : T {
40804004 currentHookNameInDev = 'useSyncExternalStore' ;
40814005 updateHookTypesDev ( ) ;
4082- return rerenderSyncExternalStore (
4083- subscribe ,
4084- getSnapshot ,
4085- getServerSnapshot ,
4086- ) ;
4006+ return updateSyncExternalStore ( subscribe , getSnapshot , getServerSnapshot ) ;
40874007 } ,
40884008 useId(): string {
40894009 currentHookNameInDev = 'useId' ;
@@ -4664,11 +4584,7 @@ if (__DEV__) {
46644584 currentHookNameInDev = 'useSyncExternalStore' ;
46654585 warnInvalidHookAccess ( ) ;
46664586 updateHookTypesDev ( ) ;
4667- return rerenderSyncExternalStore (
4668- subscribe ,
4669- getSnapshot ,
4670- getServerSnapshot ,
4671- ) ;
4587+ return updateSyncExternalStore ( subscribe , getSnapshot , getServerSnapshot ) ;
46724588 } ,
46734589 useId(): string {
46744590 currentHookNameInDev = 'useId' ;
0 commit comments