【问题标题】:Yup / Formik async validation with debounce是的 / Formik 异步验证与去抖动
【发布时间】:2020-02-22 21:16:55
【问题描述】:

如何将 debounce 应用于下面的异步验证 (code from Yup's github)?

let asyncJimmySchema = string().test(
  'is-jimmy',
  '${path} is not Jimmy',
  async (value) => (await fetch('/is-jimmy/' + value)).responseText === 'true',
});

【问题讨论】:

    标签: reactjs formik yup


    【解决方案1】:

    您可以使用lodash.debounce自行实现:

    import { debounce } from "lodash";
    
    // ...
    
    const ASYNC_VALIDATION_TIMEOUT_IN_MS = 1000;
    
    const validationFunction = async (value, resolve) => {
      try {
        const response = await fetch('/is-jimmy/' + value);
        resolve(response.responseText === 'true');
      } catch (error) {
        resolve(false);
      }
    };
    
    const validationDebounced = debounce(validationNameFunction, ASYNC_VALIDATION_TIMEOUT_IN_MS);
    

    然后在验证方案中:

    let asyncJimmySchema = string().test(
      'is-jimmy',
      '${path} is not Jimmy',
      value => new Promise(resolve => validationDebounced(value, resolve)),
    });
    

    【讨论】:

    • 听起来不错,但我无法让它工作 :( 使用正确的值调用解析函数,但似乎没有检索到它...
    【解决方案2】:

    我认为这应该可行。它从just-debounce-it 复制解决方案,但立即返回Promise,这是Yup 所期望的。

    const asyncDebouncer = (fn, wait, callFirst) => {
      var timeout;
      return function() {
        return new Promise(async (resolve) => {
          if (!wait) {
            const result = await fn.apply(this, arguments);
            resolve(result);
          }
    
          var context = this;
          var args = arguments;
          var callNow = callFirst && !timeout;
          clearTimeout(timeout);
          timeout = setTimeout(async function() {
            timeout = null;
            if (!callNow) {
              const result = await fn.apply(context, args);
              resolve(result);
            }
          }, wait);
    
          if (callNow) {
            const result = await fn.apply(this, arguments);
            resolve(result);
          }
        });
      };
    };
    
    let asyncJimmySchema = string().test(
      'is-jimmy',
      '${path} is not Jimmy',
      asyncDebouncer((value) => (await fetch('/is-jimmy/' + value)).responseText === 'true', 400),
    });
    

    【讨论】:

      猜你喜欢
      • 2019-03-15
      • 2023-03-12
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 2018-08-17
      • 2018-12-23
      • 2019-06-05
      • 2017-10-26
      相关资源
      最近更新 更多