Rxjs在使用主题的反应文本输入组件上进行反跳不会在无状态/功能组件上批量输入文本 [英] Rxjs debounce on react text input component using Subjects does not batch input text on stateless/functional component

查看:112
本文介绍了Rxjs在使用主题的反应文本输入组件上进行反跳不会在无状态/功能组件上批量输入文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更深入地研究rxjs并发现一个问题,即我试图去抖动的输入字段在每次按键时都会调度一个事件,去抖动仅保存输出,但会导致像这样的树:

  a 
as(延迟-等待200ms,然后同步触发其余部分)
asd
asdf
asdfg
....

相同的代码在类组件中按预期工作( https://stackoverflow.com/a/44300853/1356046 )但无法理解为什么它在无状态情况下不起作用组件。例如: https://stackblitz.com/edit/react-hzhrmf -您可以请参阅useState更新为每个击键触发。



非常感谢。

解决方案

React不断调用您的函数来渲染组件。因此,主题是不断重新创建的。



使用带有useState的工厂来保留主题,并与useEffect一起使用以确保仅进行一次订阅可以解决您的问题。 / p>

类似这样的东西:

  import从'react'进行React,{Component,useState,useEffect,useRef}; 
从 react-dom导入{渲染};
import {debounceTime,地图,点击,distingtUntilChanged}来自 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),
distantUntilChanged(),
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>已反跳:{debouncedName}< / p>
< / div>
);
}

render(< App /> ;, document.getElementById(’root’));


I'm trying to dive deeper into rxjs and found an issue where the input field I'm trying to debounce dispatches an event on every keypress, the debounce only holds the output but results in a tree like:

a
as(delay - waits 200ms, then fires the rest synchronously)
asd
asdf
asdfg 
....

The same code works as expected in a class component(https://stackoverflow.com/a/44300853/1356046) but cannot understand why it doesn't work with stateless components. Here's an example: https://stackblitz.com/edit/react-hzhrmf - you can see the useState update fires for every keystroke.

Thanks a lot.

解决方案

React continuously calls your function to render the component. Therefore the Subject is continuously recreated.

Using a factory with useState to keep the subject and working with useEffect to make sure the subscription is only made once should fix your issue.

Something like this :

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'));

这篇关于Rxjs在使用主题的反应文本输入组件上进行反跳不会在无状态/功能组件上批量输入文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆