使用多个AJAX调用来反应setState

时间:2015-12-09 10:29:24

标签: ajax reactjs

我希望视图始终使用最新调用searchWiki()的结果进行更新。我已经使用了一个模块,可以将对$.ajax的重复调用解析为最近一次调用返回的值。

但它似乎仍然不同步并显示之前通话的结果。我猜这是因为setState是异步的?我应该如何保持两个异步操作同步?

此外,我意识到我应该在某个地方进行辩护,但我不确定我应该去除什么。 handleChangesearchWikilatestAjax

以下是演示: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));
  }
}

1 个答案:

答案 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 => {

    });
}