score:9

Accepted answer

solution #1

using subjects: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')) 
})

solution #2

using rxjs's 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')) 
})

solution #3

note: highly experimental, and just something i tried to do for fun.

this is more for an action based architecture, where you have actions that change your state (flux). this is a handler that is fully standalone. it is used with a custom operator 'fromeventargs': fiddle (look at the console)

const handler = (e) => {        
  rx.observable
    .fromeventargs(e, 'uniquekey') 
    .debouncetime(1000)        
    .subscribe(x => console.log('send an action', x))
}

score:0

i keep getting to this question, while i prefer this solution from another one.

copied below for simplicity. please upvote the original.


you will need to cretae observable from change events(for example using subject) and then debounce on that.

here is the fully featured example for you:

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>

score:2

try like this:

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}>
       )
    }

}

score:8

based on omerts propositions, (especially solution #1) here is my final code

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} ... />
   ...
}

Related Query

More Query from same tag