My problem may be a trivial one but I wasn't able to find the answer so far.
How can I defer (debounce) updating state in React while user is typing, to avoid unnecessary updates?
Having <input onChange={this.onChange} .../>
, how can I bind onChange event with rxjs? Should I try to make this input observable or should I use FromEventPattern?
In both cases I have no idea how to bind React events with rxjs. The second question is whether the user will see any input changes during debounce?
In the case of Debouncing, the API will trigger only once after 2 seconds, after we type our whole pin-code. First of all, create a state using the useState hook in React. const [pinCode, setPinCode] = React. useState("");
debounceTime delays the values emitted by a source for the given due time. If within this time a new value arrives, the previous pending value is dropped and the timer is reset. In this way debounceTime keeps track of most recent value and emits that most recent value when the given due time is passed.
You have 2 options to create debounced and throttled functions in React: using useCallback() or useMemo() hooks.
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'))
})
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'))
})
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))
}
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} ... />
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With