我的问题可能很简单但到目前为止我找不到答案。
如何在用户输入时推迟(去抖)更新React中的状态,以避免不必要的更新?
拥有<input onChange={this.onChange} .../>
,如何用rxjs绑定onChange事件?我应该尝试使此输入可观察,还是应该使用FromEventPattern?
在这两种情况下,我都不知道如何使用rxjs绑定React事件。 第二个问题是用户是否会在去抖期间看到任何输入变化?
答案 0 :(得分:9)
使用主题: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'))
})
使用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'))
})
注意:高度实验性,以及我为了好玩而尝试做的事情。
这更适用于基于动作的体系结构,您可以在其中执行更改状态(通量)的操作。这是一个完全独立的处理程序。它与自定义运算符'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>