@@ -469,6 +469,31 @@ const useFactory = (factory, args) => {
469
469
return current ;
470
470
}
471
471
472
+ const assignState = ( obj , target ) => {
473
+ Object . assign ( obj , target ) ;
474
+ const symbols = Object . getOwnPropertySymbols ( target ) ;
475
+ let i = symbols . length ;
476
+ while ( i -- > 0 ) {
477
+ const symbol = symbols [ i ] ;
478
+ obj [ symbol ] = target [ symbol ] ;
479
+ }
480
+ return obj ;
481
+ }
482
+
483
+ class ProtoState {
484
+ constructor ( initialState ) {
485
+ initialState && assignState ( this , initialState ) ;
486
+ }
487
+
488
+ toJSON ( ) {
489
+ const obj = { } ;
490
+ let target = this ;
491
+ do {
492
+ assignState ( obj , target ) ;
493
+ } while ( ( target = Object . getPrototypeOf ( target ) ) && target !== Object . prototype ) ;
494
+ return obj ;
495
+ }
496
+ }
472
497
473
498
/**
474
499
* useAsyncDeepState hook whose setter returns a promise
@@ -484,26 +509,27 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
484
509
throw TypeError ( 'initial state must be a plain object' ) ;
485
510
}
486
511
487
- const state = initialValue ? Object . assign ( { } , initialValue ) : { } ;
512
+ const state = new ProtoState ( initialValue ) ;
488
513
489
514
Object . assign ( current , {
490
515
state,
491
- oldState : null ,
516
+ oldState : new ProtoState ( initialValue ) ,
492
517
callbacks : new Map ( )
493
518
} )
494
519
}
495
520
496
- const [ state , setState ] = useState ( ! current . inited && Object . create ( current . state ) ) ;
497
-
498
- current . inited = true ;
521
+ const [ state , setState ] = useState ( ! current . inited && Object . freeze ( Object . create ( current . state ) ) ) ;
499
522
500
523
watch && useEffect ( ( ) => {
524
+ if ( ! current . inited ) return ;
501
525
const data = [ state , current . oldState ] ;
502
526
current . callbacks . forEach ( cb => cb ( data ) ) ;
503
527
current . callbacks . clear ( ) ;
504
- current . oldState = Object . assign ( { } , current . state ) ;
528
+ current . oldState = new ProtoState ( current . state ) ;
505
529
} , [ state ] ) ;
506
530
531
+ current . inited = true ;
532
+
507
533
return [
508
534
state ,
509
535
/**
@@ -522,7 +548,7 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
522
548
}
523
549
524
550
setState ( ( state ) => {
525
- if ( newState == null || isEqualObjects ( Object . assign ( current . state , newState ) , current . oldState ) ) {
551
+ if ( newState == null || isEqualObjects ( assignState ( current . state , newState ) , current . oldState ) ) {
526
552
scope && cb ( [ state , current . oldState ] ) ;
527
553
return state ;
528
554
}
@@ -532,7 +558,7 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
532
558
scope . onDone ( ( ) => current . callbacks . delete ( scope ) )
533
559
}
534
560
535
- return Object . create ( current . state )
561
+ return Object . freeze ( Object . create ( current . state ) ) ;
536
562
} ) ;
537
563
}
538
564
0 commit comments