我正在开发一个React游戏搜索应用程序,该应用程序从第三方来源提取API数据。当用户搜索找不到的输入时,抓取仅挂在那里而不会停止。基本上,我坚持要弄清楚如何取消获取请求(如果在说10秒后完成一次setTimeout)。如果没有收到响应,那么我希望将其取消并显示错误消息。感谢您的提前帮助!
class Search extends Component {
constructor(props) {
super(props);
this.state = {
title: "",
games: [],
error: false,
loading: false
}
}
updateInput = (event) => {
this.setState({
title: event.target.value
});
}
handleGames = (search) => {
const proxyUrl = `https://cors-anywhere.herokuapp.com/`;
const key = `8cd10a7136710c1003c8e216d85941ace5a1f00e`;
const endpoint = `https://www.giantbomb.com/api/search/?api_key=`;
const url = `${proxyUrl}${endpoint}${key}&format=json&resources=game&query=${search}&limit=30`;
this.setState({ loading: true }, () => {
fetch(url)
.then(res => res.json())
.then(data => {
const response = data.results;
response.forEach(game => {
this.setState(prevState => ({
games: prevState.games.concat(game),
loading: false
}))
});
}).catch(error => {
console.log('Request failed', error);
});
this.setState({
games: []
})
})
}
handleSubmit = (e) => {
const { title } = this.state;
e.preventDefault();
if (!title) {
this.setState({ error: true })
} else {
this.setState({ error: false })
this.handleGames(title);
}
}
render() {
const { games, error, loading } = this.state;
return (
<div className="App">
<div className="search-bar">
<form>
<input
className="input-field"
type="text"
placeholder="Search Game"
onChange={this.updateInput}
/>
<button
className="search-button"
onClick={this.handleSubmit}
>Search</button>
</form>
<span className="error">{error ? "You kind of need to type something first, genius." : ""}</span>
</div>
<div className="games-container">
{loading ? (
<div className="loading-div">
<i className="fa fa-3x fa-spinner fa-spin" />
<p className="loading">Loading....</p>
</div>
) : (
games.map(game => {
return <Game
key={game.id}
game={game}
icon={game.image.icon_url}
gameTitle={game.name}
/>
})
)
}
</div>
</div>
);
}
}
答案 0 :(得分:0)
您可以将其嵌套在Promise中,而不是直接使用访存。您会发现很多实现都在进行搜索。那是我用过的。
const advFetch = (url, ...) => {
const TIMEOUT = 10000;
let didTimeOut = false;
return new Promise(function(resolve, reject) {
const timeout = setTimeout(() => {
didTimeOut = true;
reject(new Error('Request timed out'));
}, TIMEOUT);
fetch(url, ...).then(function(response) {
clearTimeout(timeout);
if (!didTimeOut) {
resolve(response);
}
})
.catch(function(err) {
if (didTimeOut) {
return;
}
reject(err);
});
})
}
注意:获取并没有真正取消(这是不可能的),它将继续直到达到网络超时为止,但是您的应用程序将忽略它。