如何使用rxjs在reactjs中去除用户输入

时间:2016-05-19 07:05:43

标签: reactjs rxjs

我的问题可能很简单但到目前为止我找不到答案。

如何在用户输入时推迟(去抖)更新React中的状态,以避免不必要的更新?

拥有<input onChange={this.onChange} .../>,如何用rxjs绑定onChange事件?我应该尝试使此输入可观察,还是应该使用FromEventPattern?

在这两种情况下,我都不知道如何使用rxjs绑定React事件。 第二个问题是用户是否会在去抖期间看到任何输入变化?

4 个答案:

答案 0 :(得分:9)

解决方案#1

使用主题:Fiddle

const state = new Rx.Subject()
              .debounceTime(1000)
              .scan((acc) => {
                return ++acc
              }, 0).do(::console.log)


const handler = (e) => {        
  state.next(e)
}

state.startWith(0).subscribe((clicks) => {
  ReactDOM.render(<button onClick={handler}>Clicked {clicks}</button>, document.querySelector('#app')) 
})

解决方案#2

使用rxjs的fromEvent:Fiddle

// Intial render so element exists in dom (there is probably a better pattern)
ReactDOM.render( <button id='clickMe'>Click Me</button>, document.querySelector('#app')) 

const clicks = Rx.Observable
                .fromEvent(document.getElementById('clickMe'), 'click')
                .do(::console.log)
                .debounceTime(1000)
                .scan((acc) => {
                  return ++acc
                }, 0)

clicks.subscribe((clicks) => {
  ReactDOM.render( <button id='clickMe'>Click Me {clicks}</button>, document.querySelector('#app')) 
})

解决方案#3

注意:高度实验性,以及我为了好玩而尝试做的事情。

这更适用于基于动作的体系结构,您可以在其中执行更改状态(通量)的操作。这是一个完全独立的处理程序。它与自定义运算符'fromEventArgs'一起使用:Fiddle(查看控制台)

const handler = (e) => {        
  Rx.Observable
    .fromEventArgs(e, 'UniqueKey') 
    .debounceTime(1000)        
    .subscribe(x => console.log('Send an action', x))
}

答案 1 :(得分:6)

基于omerts命题,(特别是解决方案#1)这里是我的最终代码

input: Rx.Subject<any>;

constuctor(...){
   this.input = new Rx.Subject();
   this.input.debounce(1000).subscribe(this.processInput);
}

handleChange = event => {
   event.persist();
   this.input.onNext(event);

    };

processInput = x => {
   // invoke redux/flux action to update the state
}

render(){
   ...
   <input onChange={this.handleChange} ... />
   ...
}

答案 2 :(得分:1)

尝试这样:

class MyScene extends React.Component {

    constructor(props) {
        var onChangeTextObservable = Rx.Observable.fromEventPattern(
           (handler) => {this.onChangeText = handler}
        );
        onChangeTextObservable.subscribe(x => console.log(x));
    }

    render() {
       return (
          <TextInput onChangeText={this.onChangeText}>
       )
    }

}

答案 3 :(得分:0)

我一直在回答这个问题,而我更喜欢this solution from another one

为简单起见,在下面复制。请对原始文件进行投票。


您需要从变更事件中逐渐观察到(例如 使用主题),然后对此进行反跳。

这是为您提供全功能示例:

class Search extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      search: '',
      debounced: '',
    };
    this.onSearch$ = new Rx.Subject();
    this.onSearch = this.onSearch.bind(this);
  }
  componentDidMount(){
    this.subscription = this.onSearch$
      .debounceTime(300)
      .subscribe(debounced => this.setState({ debounced }));
  }
  
  componentWillUnmount() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
  
  onSearch(e) {
    const search = e.target.value;
    this.setState({ search });
    this.onSearch$.next(search);
  }

  render() {
    const { search, debounced } = this.state;
    return (
      <div>
        <input type="text" value={search} onChange={this.onSearch} />
        <div>debounced value: {debounced}</div>
      </div>
    );
  }
}

ReactDOM.render(
  <Search />,
  document.getElementById('root')
);
<script src="https://unpkg.com/rxjs@5.4.0/bundles/Rx.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

相关问题