使用主题对反应文本输入组件进行 Rxjs 反跳不会在无状态/功能组件上批量输入文本

Sin*_*ync 4 javascript rxjs debouncing

我试图更深入地研究 rxjs ,发现一个问题,我试图去抖的输入字段在每次按键时调度一个事件,去抖只保存输出,但会产生一个树,如下所示:

a
as(delay - waits 200ms, then fires the rest synchronously)
asd
asdf
asdfg 
....
Run Code Online (Sandbox Code Playgroud)

相同的代码在类组件中按预期工作(/sf/answers/3101059741/),但无法理解为什么它不适用于无状态组件。这是一个示例: https: //stackblitz.com/edit/react-hzhrmf - 您可以看到每次击键都会触发 useState 更新。

多谢。

Boy*_*yen 7

React 不断调用您的函数来渲染组件。因此,主体不断被重新创造。

使用带有 useState 的工厂来保留主题并使用 useEffect 来确保订阅仅进行一次应该可以解决您的问题。

像这样的东西:

import React, { Component, useState, useEffect, useRef } from 'react';
import { render } from 'react-dom';
import { debounceTime, map, tap, distinctUntilChanged } from 'rxjs/operators';
import { fromEvent, Subject } from 'rxjs';

import './style.css';
const App = props => {
  const [queryName, setQueryName] = useState("");
  const [debouncedName, setDebouncedName] = useState("");
  const [onSearch$] = useState(()=>new Subject());
  useEffect(() => {
    const subscription = onSearch$.pipe(
      debounceTime(400),
      distinctUntilChanged(),
      tap(a => console.log(a))
    ).subscribe(setDebouncedName);
  }, [])
  const handleSearch = e => {
    setQueryName(e.target.value);
    onSearch$.next(e.target.value);
  };

  return (
    <div>
      <input
        placeholder="Search Tags"
        value={queryName}
        onChange={handleSearch}
      />
      <p>Debounced: {debouncedName}</p>
    </div>
  );
}

render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)