How to debounce user input in reactjs using rxjs
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}>
)
}
}
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} ... />
...
}
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))
}