@@ -5,7 +5,10 @@ import { getCallerStack } from "./utils";
55
66type StateType = {
77 cursor : number ;
8- values : any [ ] ;
8+ values : {
9+ value : any ;
10+ updateQueue : any [ ] ;
11+ } [ ] ;
912} ;
1013type StateSubscriberType = ( ) => void ;
1114
@@ -29,19 +32,26 @@ function useState<T>(
2932 initialValue instanceof Function ? initialValue ( ) : initialValue ;
3033 states [ stringCallerStack ] = {
3134 cursor : 0 ,
32- values : [ savedValue ] ,
35+ values : [
36+ {
37+ updateQueue : [ ] ,
38+ value : savedValue ,
39+ } ,
40+ ] ,
3341 } ;
3442 }
3543
3644 const currentCursor = states [ stringCallerStack ] . cursor ;
3745 const currentValues = states [ stringCallerStack ] . values ;
46+ const currentUpdateQueue =
47+ states [ stringCallerStack ] . values [ currentCursor ] . updateQueue ;
3848
39- if ( currentValues [ currentCursor ] === undefined ) {
40- currentValues [ currentCursor ] = initialValue ;
49+ if ( currentValues [ currentCursor ] . value === undefined ) {
50+ currentValues [ currentCursor ] . value = initialValue ;
4151 }
4252
4353 const performUpdate : UpdaterFunctionType < T > = ( newValue ) => {
44- if ( Object . is ( currentValues [ currentCursor ] , newValue ) ) {
54+ if ( Object . is ( currentValues [ currentCursor ] . value , newValue ) ) {
4555 return ;
4656 }
4757
@@ -54,17 +64,17 @@ function useState<T>(
5464 subscriber ( ) ;
5565 }
5666
57- currentValues [ currentCursor ] =
58- newValue instanceof Function
59- ? newValue ( currentValues [ currentCursor ] )
60- : newValue ;
61-
62- ReactDOM . render ( ) ;
67+ // for batching
68+ const latestValue =
69+ currentUpdateQueue . at ( - 1 ) || currentValues [ currentCursor ] . value ;
70+ const queueItem =
71+ newValue instanceof Function ? newValue ( latestValue ) : newValue ;
72+ currentUpdateQueue . push ( queueItem ) ;
6373 } ;
6474
6575 states [ stringCallerStack ] . cursor ++ ;
6676
67- return [ currentValues [ currentCursor ] , performUpdate ] ;
77+ return [ currentValues [ currentCursor ] . value , performUpdate ] ;
6878}
6979
7080componentRegistry . subscribeToStoreChange (
@@ -84,4 +94,20 @@ export function subscribeToStateChange(callback: StateSubscriberType) {
8494 stateSubscribers . push ( callback ) ;
8595}
8696
97+ export function flushStateUpdates ( ) {
98+ for ( const key in states ) {
99+ for ( let i = 0 ; i < states [ key ] . values . length ; i ++ ) {
100+ const state = states [ key ] . values [ i ] ;
101+ // prevent from falsy undefined assignment
102+ if ( state . updateQueue . length === 0 ) {
103+ continue ;
104+ }
105+
106+ state . value = state . updateQueue . at ( - 1 ) ;
107+ state . updateQueue = [ ] ;
108+ }
109+ }
110+ ReactDOM . render ( ) ;
111+ }
112+
87113export default useState ;
0 commit comments