3

这是一个很常见的查询,但我对新final-form库有点困惑。我曾经使用过,redux-form但这个新版本太不一样了。

我的需求很简单,我想在用户写一些文本时分派搜索,但我想throttle在字段中添加一个。

这是 lib 的第一次尝试react-final-form-listeners,但正如您将看到的,当您在文本字段中写入时,去抖动不起作用:/

https://codesandbox.io/embed/react-final-form-simple-example-khkof

4

3 回答 3

1

首先,我鼓励您在不使用模糊的包层的情况下完成所有这些操作。这将帮助您真正了解流程,但是,以下是在输入更改时调用函数的方法:

  • debounce(仅在用户停止输入 500 毫秒时执行一次)
  • 油门(批处理然后每 500 毫秒执行一次)
  • 正常(在每次输入更新时执行)

在这种情况下,我只是在 render 方法之外创建了一个 debounced 函数。这在使用类而不是钩子时会有所不同:

挂钩:

const handleSearch = debounce(searchText => { ... }, 500);

类(或者您可以在 中对类字段进行去抖动constructor,或者工作):

class Example extends Component {
  handleSearch = debounce(searchText => { ... }, 500)

  render = () => { ... }
}

工作示例 (在代码框控制台打开时键入):

编辑 React 最终形式 - 简单示例


去抖动、节流和正常执行的区别:

在此处输入图像描述


和上面一样,减去react-final-formreact-final-form-listeners(你的项目中少了两个依赖项!):

工作示例(在代码框控制台打开时键入):

编辑简单表单 - 简单示例


于 2019-08-03T06:16:50.703 回答
0

您的解决方案存在多个问题:

  • 使用 lodashdebounce而不是throttle.
  • 在表单外创建去抖动函数,以防止在每次重新渲染或更改时重新分配
  • 调用表单提交操作,而不是提交处理程序handleSubmit

修改并运行您的示例:

编辑 React 最终形式 - 简单示例

于 2020-03-19T08:07:18.680 回答
0

这是一个记忆的去抖版本:

export default function DebouncedMemoizedField({
  milliseconds = 400,
  validate,
  ...props
}) {
  const timeout = useRef(null);
  const lastValue = useRef(null);
  const lastResult = useRef(null);

  const validateField = (value, values, meta) => new Promise((resolve) => {
    if (timeout.current) {
      timeout.current();
    }

    if (value !== lastValue.current) {
      const timerId = setTimeout(() => {
        lastValue.current = value;
        lastResult.current = validate(value, values, meta);
        resolve(lastResult.current);
      }, milliseconds);

      timeout.current = () => {
        clearTimeout(timerId);
        resolve(true);
      };
    } else {
      resolve(lastResult.current);
    }
  });

  return <Field validate={validateField} {...props} />;
}

用法:

<MemoizedDebouncedValidationField
  name="username"
  validate={(value) => (value === 'jim' ? 'Username exists' : undefined)}
  render={({ input, meta }) => (
    <>
      <input {...input} />
      {(meta.touched && meta.error) && <p>Error</p>}
    </>
  )}
/>
于 2022-01-10T18:32:14.523 回答