utils/mobx: add disposableDebouncedReaction

process/configurator: use disposableDebouncedReaction for getTarifs reaction
This commit is contained in:
vchikalkin 2024-02-06 13:36:56 +03:00
parent 4c3d305e7f
commit e69a0ec781
2 changed files with 41 additions and 2 deletions

View File

@ -3,7 +3,7 @@ import type { Elements } from '@/Components/Calculation/config/map/values';
import * as CRMTypes from '@/graphql/crm.types';
import type { ProcessContext } from '@/process/types';
import { normalizeOptions } from '@/utils/entity';
import { disposableReaction } from '@/utils/mobx';
import { disposableDebouncedReaction, disposableReaction } from '@/utils/mobx';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { comparer, reaction } from 'mobx';
@ -15,7 +15,7 @@ export default function valuesReactions({ store, apolloClient }: ProcessContext)
const { getTarifs, getRates, getPriceChange } = helper({ apolloClient });
disposableReaction(
disposableDebouncedReaction(
() => $process.has('LoadKP'),
() =>
$calculation.$values.getValues([
@ -39,6 +39,7 @@ export default function valuesReactions({ store, apolloClient }: ProcessContext)
delay: 10,
equals: comparer.shallow,
fireImmediately: true,
wait: 100,
}
);

View File

@ -51,3 +51,41 @@ export function debouncedReaction<T, FireImmediately extends boolean = false>(
return reaction(expression, debouncedEffect, reactionOpts);
}
export function disposableDebouncedReaction<T, FireImmediately extends boolean = false>(
disposeExpression: () => boolean,
expression: (r: IReactionPublic) => T,
effect: (
arg: T,
prev: FireImmediately extends true ? T | undefined : T,
r: IReactionPublic
) => void,
{ wait, ...reactionOpts }: IReactionOptions<T, FireImmediately> & { wait: number }
) {
const debouncedEffect = debounce({ delay: wait }, effect);
let disposer: IReactionDisposer | undefined;
if (!disposeExpression()) {
disposer = reaction(expression, debouncedEffect, reactionOpts);
}
function cleanDisposer() {
disposer = undefined;
}
reaction(disposeExpression, (mustBeDisposed) => {
if (mustBeDisposed) {
if (disposer !== undefined) disposer();
cleanDisposer();
} else {
setTimeout(() => {
disposer = reaction(
expression,
debouncedEffect,
reactionOpts ? omit(reactionOpts, ['fireImmediately']) : undefined
);
}, 100);
}
});
}