首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Subject的react文本输入组件上的Rxjs去反弹不会在无状态/功能组件上批量输入文本

使用Subject的react文本输入组件上的Rxjs去反弹不会在无状态/功能组件上批量输入文本
EN

Stack Overflow用户
提问于 2019-10-23 18:32:13
回答 2查看 1K关注 0票数 3

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

代码语言:javascript
复制
a
as(delay - waits 200ms, then fires the rest synchronously)
asd
asdf
asdfg 
....

在类组件(https://stackoverflow.com/a/44300853/1356046)中,相同的代码可以正常工作,但无法理解为什么它不能与无状态组件一起工作。这里有一个例子:https://stackblitz.com/edit/react-hzhrmf -你可以看到每次击键都会触发useState更新。

非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-23 19:36:05

React不断地调用您的函数来呈现组件。因此,主题被不断地重新创建。

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

如下所示:

代码语言:javascript
复制
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'));
票数 3
EN

Stack Overflow用户

发布于 2020-05-05 18:12:16

这里有一个自定义钩子的版本,因为它可能会在一个表单中被多次使用,否则会弄乱你的代码。

代码语言:javascript
复制
function useDebounce<T = any>(time: number, defaultValue: T): [T, (v: T) => void] {
  let [value, setValue] = React.useState<T>(defaultValue);
  let [value$] = React.useState(() => new Subject<T>());
  React.useEffect(() => {
    let sub = value$.pipe(debounceTime(time)).subscribe(setValue);
    return () => sub.unsubscribe();
  }, [time, value$]);
 return [value, (v) => value$.next(v)];
}

//useage: 
let [value,setValue] = useDebounce(200,"");
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58520864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档