Javascript 通过输入框进行异步数据检索落后了一步
我正在根据用户的输入制作一个简单的Wikipedia结果查看器 结果列表应在输入框更改时随时更新 我正在使用Javascript 通过输入框进行异步数据检索落后了一步,javascript,asynchronous,reactjs,state,Javascript,Asynchronous,Reactjs,State,我正在根据用户的输入制作一个简单的Wikipedia结果查看器 结果列表应在输入框更改时随时更新 我正在使用$.getJSON()调用WikipediaAPI。但是,无论何时更改输入框,我的结果列表都不会更新。事实上,它似乎落后了一步,所以在更新状态方面肯定有一些我不理解的地方,特别是在异步调用中 话虽如此,正如我在控制台中看到的那样,响应确实会发生预期的变化,因此在呈现结果列表时发生了一些我不理解的事情 从React调试工具和控制台中,我可以看到我的阵列正在按预期进行更新,如下所示: HTM
$.getJSON()
调用WikipediaAPI。但是,无论何时更改输入框,我的结果列表都不会更新。事实上,它似乎落后了一步,所以在更新状态方面肯定有一些我不理解的地方,特别是在异步调用中
话虽如此,正如我在控制台中看到的那样,响应确实会发生预期的变化,因此在呈现结果列表时发生了一些我不理解的事情
从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'));
var SearchBox=React.createClass({
changeText:函数(){
this.props.changeInputText(ReactDOM.findDOMNode(this.refs.searchBox).value);
},
渲染:函数(){
返回(
)
}
});
var SearchItemList=React.createClass({
渲染:函数(){
log('data:',this.props.results);
console.log('inputtext',this.props.inputtext);
var listItems=this.props.results
.过滤器(功能(e,i){
返回e.title.indexOf(this.props.inputText)!=-1;
}.绑定(本)
.map(功能(e,i){
返回(
{e.snippet}
)
});
返回(
{listItems}
)
}
});
//TODO:是否将列表项提取到其自己的组件中?
var Main=React.createClass({
getInitialState:函数(){
返回{
inputText:'javascript',
结果:[],
}
},
getWikiData:函数(){
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、函数(数据){
这是我的国家(
{结果:data.query.search}
);
}.约束(这个);
},
componentDidMount:函数(){
这是getWikiData();
},
changeInputText:函数(搜索术语){
这是我的国家({
inputText:searchTerm,
});
这是getWikiData();
},
渲染:函数(){
返回(
维基搜索者
)
}
});
ReactDOM.render(,document.getElementById('container'));
主要错误在于您假设在调用
getWikiData
之前,在changeInputText
函数中调用setState
,将会更改inputText
setState
是一个异步函数,因此当启动getWikiData
时,inputText
的新值可能无法设置
因此,要修复此问题,请在回调中调用getWikiData
,该回调将在更新新状态时触发
changeInputText: function (searchTerm) {
this.setState({
inputText: searchTerm,
}, () => {
this.getWikiData();
});
},
主要错误在于您假设在调用
getWikiData
之前,在changeInputText
函数中调用setState
将更改inputText
setState
是一个异步函数,因此当启动getWikiData
时,inputText
的新值可能无法设置
因此,要修复此问题,请在回调中调用getWikiData
,该回调将在更新新状态时触发
changeInputText: function (searchTerm) {
this.setState({
inputText: searchTerm,
}, () => {
this.getWikiData();
});
},
顺便说一句,关于工作plunker和all的问题很好。顺便说一句,关于工作plunker和all的问题很好。谢谢你,它帮助我了解了更多关于
setState()
。然而,我仍然无法填充我的列表。它似乎不再“落后一步”,但它可以选择何时填充列表。例如,查询ton
会生成一个列表,但是tony
没有显示任何内容。有什么想法吗?谢谢你,它帮助我更多地了解了setState()
。然而,我仍然无法填充我的列表。它似乎不再“落后一步”,但它可以选择何时填充列表。例如,查询ton
会生成一个列表,但是tony
没有显示任何内容。有什么想法吗?