通过输入框检索异步数据落后了一步
Posted
技术标签:
【中文标题】通过输入框检索异步数据落后了一步【英文标题】:Async data retrieval via input box is one step behind 【发布时间】:2016-03-26 22:56:22 【问题描述】:我正在根据用户的输入制作一个简单的***结果查看器。
只要输入框发生变化,结果列表就会更新。
我正在使用 $.getJSON()
来调用 Wikipedia API。但是,无论何时更改输入框,我的结果列表都不会更新。事实上,它似乎落后了一步,所以在更新状态方面肯定有一些我不理解的东西,特别是在异步调用中。
话虽如此,响应确实发生了变化,正如我在控制台中看到的那样,所以在结果列表的呈现中发生了一些我不理解的事情。
从 React 调试工具和控制台,我可以看到我的数组正在按预期更新,如下所示:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Wiki Searcher</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
</head>
<body>
<div id="container"></div>
<script src="script.js"></script>
</body>
</html>
Javascript
var SearchBox = React.createClass(
changeText: function ()
this.props.changeInputText(ReactDOM.findDOMNode(this.refs.searchBox).value);
,
render: function ()
return (
<input type="text" onChange=this.changeText ref="searchBox"/>
)
);
var SearchItemList = React.createClass(
render: function ()
console.log('data:', this.props.results);
console.log('inputtext', this.props.inputText);
var listItems = this.props.results
.filter(function (e, i)
return e.title.indexOf(this.props.inputText) !== -1;
.bind(this))
.map(function (e, i)
return (
<li key=i>
<a href="#"><h3>e.title</h3></a>
<p>e.snippet</p>
</li>
)
);
return (
<ul>
listItems
</ul>
)
);
//TODO: extract list item into its own component?
var Main = React.createClass(
getInitialState: function ()
return
inputText: 'javascript',
results: [],
,
getWikiData: function ()
var prependage = 'https://en.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch='
var appendage = "&callback=?";
var url = prependage + this.state.inputText + appendage;
$.getJSON(url, function (data)
this.setState(
results: data.query.search
);
.bind(this));
,
componentDidMount: function ()
this.getWikiData();
,
changeInputText: function (searchTerm)
this.setState(
inputText: searchTerm,
);
this.getWikiData();
,
render: function ()
return (
<div className="container">
<div className="col-sm-8 col-sm-offset-2">
<h1>Wiki Searcher</h1>
<SearchBox inputText=this.state.inputText changeInputText=this.changeInputText/>
<SearchItemList results=this.state.results inputText=this.state.inputText/>
</div>
</div>
)
);
ReactDOM.render(<Main/>, document.getElementById('container'));
Plunkr
【问题讨论】:
顺便说一句,工作人员和所有工作人员的好问题。 【参考方案1】:主要错误在于您假设在您的changeInputText
函数中调用setState
会在您调用getWikiData
之前更改inputText
。
setState
是一个异步函数,因此当您的getWikiData
触发时,inputText
的新值可能不会被设置。
所以要修复,请在回调中调用getWikiData
,当新状态更新时将触发。
changeInputText: function (searchTerm)
this.setState(
inputText: searchTerm,
, () =>
this.getWikiData();
);
,
【讨论】:
谢谢你,它帮助我更多地了解setState()
。但是,我仍然无法填充我的列表。它似乎不再“落后一步”,但它确实选择了何时填充列表。例如,查询ton
生成了一个列表,但tony
没有出现任何内容。有什么想法吗?以上是关于通过输入框检索异步数据落后了一步的主要内容,如果未能解决你的问题,请参考以下文章