我希望视图始终使用最新调用searchWiki()
的结果进行更新。我已经使用了一个模块,可以将对$.ajax
的重复调用解析为最近一次调用返回的值。
但它似乎仍然不同步并显示之前通话的结果。我猜这是因为setState
是异步的?我应该如何保持两个异步操作同步?
此外,我意识到我应该在某个地方进行辩护,但我不确定我应该去除什么。 handleChange
,searchWiki
或latestAjax
?
以下是演示:http://codepen.io/prashcr/pen/obXvWv
尝试输入内容然后退回以查看我的意思。
搜索组件
<div style={style}>
<input
value={this.props.search}
// this calls searchWiki with e.target.value
onInput={this.handleChange}
/>
</div>
父组件的searchWiki函数
searchWiki (search) {
console.log('searchWiki called with: ' + search);
if (!search) {
this.setState({results: []});
}
else {
// "latest" taken from https://github.com/bjoerge/promise-latest
let latestAjax = latest($.ajax);
let options = {
url: this.props.url + search,
dataType: 'jsonp'
};
latestAjax(options)
.then(data => {
var results = data.query.search.map(res => {
res.url = 'http://en.wikipedia.org/wiki/' + encodeURIComponent(res.title);
return res;
});
this.setState({results: results});
})
.error(e => console.log(e.message));
}
}
答案 0 :(得分:1)
handleChange
函数过于通用,无法使用硬编码值进行去抖动,因为您可能希望在其他位置使用此搜索组件。但是,您仍然希望尽早捕获重复操作,并确保它不会做任何不必要的工作。
因此我建议您使用可选的道具去除handleChange
函数,默认为0ms。
getDefaultProps() {
return {
debounce: 0
};
},
render() {
// ...
return (
<div style={style}>
<input
// ...
onInput={debounce(this.handleChange, this.props.debounce)}/>
</div>
);
}
然后确保在想要去除处理程序的时候通过此道具。
<Search onSearch={this.searchWiki} debounce={1000} />
您的其他问题正在发生,因为您在latest
函数中调用searchWiki
并且只调用返回的函数一次!每次拨打searchWiki
时,都会创建一个新的latestAjax
功能。
要使其正常工作,您需要多次调用返回的函数。
这意味着在$.ajax
函数之外定义包装的searchWiki
函数。
latestAjax: latest($.ajax),
searchWiki(search) {
// ...
this.latestAjax(options)
.then(data => {
});
}