@@ -372,43 +372,58 @@ export function useTracker<T, K extends undefined | T = undefined>(
372
372
return meteorData
373
373
}
374
374
375
- function useReadyState ( ) : {
376
- ready : boolean
377
- setReady : ( value : boolean ) => void
378
- cancelPreviousReady : ( timeout : number ) => void
375
+ /**
376
+ * A hook to track a boolean state with a sort of histeresis, with preference for `true`. `setState` makes the returned
377
+ * `state` be `true` immediately, but `false` only after `resetState` is called and `timeout` elapses. If `setState`
378
+ * is called with `true` before `timeout` elapses, then `resetState` is aborted and `state` will remain `ture.
379
+ *
380
+ * Later `resetState` calls replace earlier unelapsed calls and their timeout periods.
381
+ *
382
+ * @param {boolean } [initialState=false]
383
+ * @return {* } {{
384
+ * state: boolean
385
+ * setState: (value: boolean) => void
386
+ * resetState: (timeout: number) => void
387
+ * }}
388
+ */
389
+ function useDelayState ( initialState = false ) : {
390
+ state : boolean
391
+ setState : ( value : boolean ) => void
392
+ resetState : ( timeout : number ) => void
379
393
} {
380
- const [ ready , setReady ] = useState ( false )
381
- const [ prevReady , setPrevReady ] = useState ( false )
394
+ const [ state , setState ] = useState ( initialState )
395
+ const [ prevState , setPrevState ] = useState ( initialState )
382
396
const prevReadyTimeoutRef = useRef < number | null > ( null )
383
397
384
- const setIsReady = useCallback (
398
+ const setStateAndClearResets = useCallback (
385
399
( value : boolean ) => {
386
- setReady ( value )
400
+ setState ( value )
387
401
388
402
if ( value ) {
389
- setPrevReady ( true )
403
+ setPrevState ( true )
390
404
if ( prevReadyTimeoutRef . current !== null ) {
391
405
window . clearTimeout ( prevReadyTimeoutRef . current )
392
406
prevReadyTimeoutRef . current = null
393
407
}
394
408
}
395
409
} ,
396
- [ setReady , setPrevReady ]
410
+ [ setState , setPrevState ]
397
411
)
398
412
399
- const cancelPrevReady = useCallback (
400
- ( timeout : number ) => {
401
- prevReadyTimeoutRef . current = window . setTimeout ( ( ) => {
402
- setPrevReady ( false )
403
- } , timeout )
404
- } ,
405
- [ prevReadyTimeoutRef ]
406
- )
413
+ const resetStateAfterDelay = useCallback ( ( timeout : number ) => {
414
+ if ( prevReadyTimeoutRef . current !== null ) {
415
+ window . clearTimeout ( prevReadyTimeoutRef . current )
416
+ }
417
+ prevReadyTimeoutRef . current = window . setTimeout ( ( ) => {
418
+ prevReadyTimeoutRef . current = null
419
+ setPrevState ( false )
420
+ } , timeout )
421
+ } , [ ] )
407
422
408
423
return {
409
- ready : ready || prevReady ,
410
- setReady : setIsReady ,
411
- cancelPreviousReady : cancelPrevReady ,
424
+ state : state || prevState ,
425
+ setState : setStateAndClearResets ,
426
+ resetState : resetStateAfterDelay ,
412
427
}
413
428
}
414
429
@@ -425,7 +440,7 @@ export function useSubscription<K extends keyof AllPubSubTypes>(
425
440
sub : K ,
426
441
...args : Parameters < AllPubSubTypes [ K ] >
427
442
) : boolean {
428
- const { ready, setReady, cancelPreviousReady } = useReadyState ( )
443
+ const { state : ready , setState : setReady , resetState : cancelPreviousReady } = useDelayState ( )
429
444
430
445
useEffect ( ( ) => {
431
446
const subscription = Tracker . nonreactive ( ( ) => meteorSubscribe ( sub , ...args ) )
@@ -465,7 +480,7 @@ export function useSubscriptionIfEnabled<K extends keyof AllPubSubTypes>(
465
480
enable : boolean ,
466
481
...args : Parameters < AllPubSubTypes [ K ] >
467
482
) : boolean {
468
- const { ready, setReady, cancelPreviousReady } = useReadyState ( )
483
+ const { state : ready , setState : setReady , resetState : cancelPreviousReady } = useDelayState ( )
469
484
470
485
useEffect ( ( ) => {
471
486
if ( ! enable ) {
@@ -510,7 +525,7 @@ export function useSubscriptionIfEnabledReadyOnce<K extends keyof AllPubSubTypes
510
525
enable : boolean ,
511
526
...args : Parameters < AllPubSubTypes [ K ] >
512
527
) : boolean {
513
- const { ready, setReady, cancelPreviousReady } = useReadyState ( )
528
+ const { state : ready , setState : setReady , resetState : cancelPreviousReady } = useDelayState ( )
514
529
515
530
useEffect ( ( ) => {
516
531
if ( ! enable ) {
0 commit comments