Skip to content

Commit 0915b17

Browse files
committedMay 23, 2021
Added the ability for useAsyncWatcher and useAsyncDeepState to unsubscribe from state updates;
1 parent e87d746 commit 0915b17

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed
 

‎lib/use-async-effect.js

+21-11
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
451451
Object.assign(current, {
452452
state,
453453
oldState: null,
454-
callbacks: []
454+
callbacks: new Map()
455455
})
456456
}
457457

@@ -462,7 +462,7 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
462462
watch && useEffect(()=>{
463463
const data= [state, current.oldState];
464464
current.callbacks.forEach(cb=> cb(data));
465-
current.callbacks.length= 0;
465+
current.callbacks.clear();
466466
current.oldState= Object.assign({}, current.state);
467467
}, [state]);
468468

@@ -474,7 +474,7 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
474474
* @returns {Promise<*>|undefined}
475475
*/
476476
function (newState) {
477-
const setter= (cb)=>{
477+
const setter= (scope, cb)=>{
478478
if (typeof newState === 'function') {
479479
newState = newState(current.state);
480480
}
@@ -485,11 +485,14 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
485485

486486
setState((state)=>{
487487
if(newState == null || isEqualObjects(Object.assign(current.state, newState), current.oldState)){
488-
cb && cb([state, current.oldState]);
488+
scope && cb([state, current.oldState]);
489489
return state;
490490
}
491491

492-
cb && current.callbacks.push(cb);
492+
if (scope) {
493+
current.callbacks.set(scope, cb);
494+
scope.onDone(() => current.callbacks.delete(scope))
495+
}
493496

494497
return Object.create(current.state)
495498
});
@@ -500,27 +503,30 @@ const useAsyncDeepState = (initialValue, {watch= true}= {}) => {
500503
return;
501504
}
502505

503-
return new CPromise((resolve) => {
504-
setter(resolve);
506+
return new CPromise((resolve, reject, scope) => {
507+
setter(scope, resolve);
505508
});
506509
}
507510
]
508511
}
509512

510513
const useAsyncWatcher = (...value) => {
511514
const ref = useRef({
512-
callbacks: [],
513515
oldValue: value
514516
});
515517

518+
if (!ref.current.callbacks) {
519+
ref.current.callbacks = new Map()
520+
}
521+
516522
const multiple= value.length > 1;
517523

518524
useEffect(() => {
519525
const {current} = ref;
520526
const data = multiple ? value.map((value, index) => [value, current.oldValue[index]]) :
521527
[value[0], current.oldValue[0]];
522528
current.callbacks.forEach(cb => cb(data));
523-
current.callbacks = [];
529+
current.callbacks.clear();
524530
current.oldValue = value;
525531
}, value);
526532

@@ -529,14 +535,18 @@ const useAsyncWatcher = (...value) => {
529535
* @returns {Promise}
530536
*/
531537
return (grabPrevValue) => {
532-
return new Promise((resolve) => {
533-
ref.current.callbacks.push(entry => {
538+
return new CPromise((resolve, reject, scope) => {
539+
ref.current.callbacks.set(scope, entry => {
534540
if (multiple) {
535541
resolve(grabPrevValue ? entry : entry.map(values => values[0]))
536542
}
537543

538544
resolve(grabPrevValue ? entry : entry[0]);
539545
});
546+
547+
scope.onDone(()=>{
548+
ref.current.callbacks.delete(scope);
549+
})
540550
});
541551
}
542552
}

0 commit comments

Comments
 (0)