diff --git a/package.json b/package.json index 3d14f2c..35cfb12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "formstate-x", - "version": "1.0.7", + "version": "1.0.8", "description": "Extended alternative for formstate", "repository": { "type": "git", diff --git a/src/fieldState.spec.ts b/src/fieldState.spec.ts index 92695dc..83b1efc 100644 --- a/src/fieldState.spec.ts +++ b/src/fieldState.spec.ts @@ -375,4 +375,29 @@ describe('FieldState validation', () => { state.dispose() }) + + it('should work well with delay', async () => { + const state = new FieldState('0', 1000) + + state.onChange('1') + expect(state.value).toBe('0') + await delay(250) + expect(state.value).toBe('0') + + state.onChange('2') + expect(state.value).toBe('0') + await delay(500) + expect(state.value).toBe('0') + + state.onChange('3') + expect(state.value).toBe('0') + await delay(750) + expect(state.value).toBe('0') + + state.onChange('4') + expect(state.value).toBe('0') + await delay(1250) + expect(state.value).toBe('4') + + }) }) diff --git a/src/fieldState.ts b/src/fieldState.ts index 37c71f2..cc93229 100644 --- a/src/fieldState.ts +++ b/src/fieldState.ts @@ -1,6 +1,6 @@ import { observable, computed, action, reaction, autorun, runInAction, when } from 'mobx' import { ComposibleValidatable, Validator, Validated, ValidationResponse, ValidateStatus } from './types' -import { applyValidators } from './utils' +import { applyValidators, debounce } from './utils' import Disposable from './disposable' /** @@ -233,14 +233,17 @@ export default class FieldState extends Disposable implements Composible // debounced reaction to `_value` change this.addDisposer(reaction( () => this._value, - () => { + // use debounce instead of reactionOptions.delay + // cause the later do throttle in fact, not debounce + // see https://github.com/mobxjs/mobx/issues/1956 + debounce(() => { if (this.value !== this._value) { this.value = this._value this._validateStatus = ValidateStatus.NotValidated this._activated = true } - }, - { delay, name: 'reaction-when-_value-change' } + }, delay), + { name: 'reaction-when-_value-change' } )) // auto sync when validate ok: this.value -> this.$ diff --git a/src/utils.ts b/src/utils.ts index f3786f9..8fc1758 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -55,3 +55,13 @@ export function applyValidators(value: TValue, validators: Validator void, delay: number) { + let timeout: any = null + return () => { + if (timeout) { + clearTimeout(timeout) + } + timeout = setTimeout(fn, delay) + } +}