击键和节流的异步验证(不模糊)

asyncValidation on key strokes and throttled (not on blur)

redux-form asyncValidation 很棒,但它只适用于模糊。是否有可能让它在按键期间发生并受到限制?所以它仅每 300 毫秒运行一次,并根据最终值运行?

可能吗?简短的回答是肯定的。

难不难?好吧,正如您提到的,asyncValidation for redux-form 选项仅适用于 onBlur,而您希望它适用于 onChange.

因此您可以分叉并将此功能添加到 redux-form 中,这样您就可以这样做:

@reduxForm({
  form: 'login',
  asyncValidate: validator,
  //asyncBlurFields: ['username','password'],
  asyncChangeFields: ['username','password'], /* add this new option */
})

对于去抖动部分,您希望以某种方式去抖动 onChange 处理程序而不是验证函数本身,这会带来另一个选择...

redux-form 导出其内部动作创建器,这可能足以将其组合在一起。特别是 stopAsyncValidation action creator that lets you pass field-level async errors directly into a form. Pair that with the onChange 支持 Field,你实际上有正确的部分来完成它:

import React from 'react'
import { Field, reduxForm, stopAsyncValidation } from 'redux-form'
import _debounce from 'lodash.debounce'

import renderField from './renderField'

@reduxForm({form: 'debouncedOnChangeValidation'})
class DebouncedOnChangeValidationForm extends React.Component {

  customValidate = () => {
    const { form, dispatch } = this.props
    dispatch(stopAsyncValidation(form, { username: "thats wrong..." })) /* pass in async error directly! */
  }

  debounceValidate = _debounce(this.customValidate, 1000) /* decorate with debounce! */

  render() {
    const { handleSubmit, pristine, reset, submitting} = this.props
    return (
      <form onSubmit={handleSubmit}>
        <Field name="username" type="text"
          component={renderField} label="Username"
          onChange={this.debounceValidate} /* bind validation to onChange! */
        />
        <div>
          <button type="submit" disabled={submitting}>Submit</button>
          <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
        </div>
      </form>
    )
  }
}

此外,要访问用于执行验证的表单值,您需要使用 getFormValues 选择器。

当然,这不会像更内置的解决方案那样强大,但对于某些用例来说它可能工作得很好。