我有一个名为request
的函数,它对API进行AJAX调用,并返回一些JSON数据。 RenderEntry创建一个Entry组件,它基本上只是一个带有h3元素的div。 h3元素应该来自request
返回的JSON数据。
在RenderEntry
中,我尝试使用传递给它的request
来调用id
,将其分配给常量data
,然后传递{{1} }}作为道具进入data.name
。但是,Entry
未定义。
事实上,这是我用data
引导的拳头反应应用程序。我知道create-react-app
在将文字request
传入其中时有效,但我不明白为什么它在这个函数中不起作用。
id
答案 0 :(得分:0)
在XMLHttpRequest中考虑send,onload和onerror的方法是send发出获取信息的请求。此信息将在稍后返回。同时,它所处的功能完成,因为你没有返回,它默认返回'undefined'。这就是你从console.log(request(id))调用中得到'undefined'的原因。
当最终检索数据时,调用onload()或onerror()函数(如果检索成功,则为前者;如果发生错误,则调用后者。从XMLHttpRequest中调用这些函数,而不是从代码中调用所以你的代码看不到onload()的返回。
为了获取数据,您需要提供一个在数据最终到达时将被调用的函数 - 这称为'回调'函数,它指的是在异步操作之后调用的任何函数(一个触发后会响应一段时间。)
您的request()函数需要进行一些小的更改,如下所示:
function request(id, callback) {
const base = 'https://url.com/'
const request = new XMLHttpRequest();
request.open('GET', base + id, true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
const data = JSON.parse(this.response);
// console.log(data);
callback(data);
} else {
console.log('We reached our target server, but it returned an error!');
}
};
request.onerror = function() {
console.log('There was a connection error of some sort');
};
request.send();
}
现在要调用此函数,您可以执行以下操作:
function showData(data) {
console.log(data);
}
request(id, showData);
这应该在控制台中显示您的数据。
我对React如何工作的细节并不十分熟悉,所以我相信有更多有能力的人可以帮助解决这部分问题。如果没有,你仍然被困住让我知道,我将尽我所能进一步澄清。
将两个回调函数传递给管理XMLHttpRequest的函数(在您的情况下为request())并不罕见 - 如果成功检索数据则调用一个,如果发生错误则调用另一个。像这样:
function showData(data) {
console.log(data);
}
function reportError(errResponse) {
console.warn(errResponse);
}
request(id, showData, reportError);
或者传递一个带有两个参数的回调,一个用于错误,一个用于数据(如果成功)。像这样:
function receiveData(errResponse, data) {
if (errResponse) {
console.warn(errResponse);
}
else {
console.log(data);
}
}
然后,您需要调整request()函数以使用适当的参数调用回调函数:
callback(null, data); // if you get the data successfully
callback("Unable to retrieve data"); // if you get an error
这里有一个link,其中包含有关从XMLHttpRequest获取数据的更多信息,以及another有关获取异步和同步函数调用之间差异的信息。
答案 1 :(得分:0)
这就是代码应该如何:
function Entry(props) {
return (
<div>
<h3>{props.name}</h3>
</div>
);
}
class App extends Component {
constructor(...args){
super(...args)
this.state = {}
request(8000);
}
render() {
if(this.state.error) return (..error view)
if(!this.state.data) return (..empty view of loader)
return (<Entry name={this.state.data.name}/>)
}
}
function request(id) {
const base = 'https://url.com/'
const request = new XMLHttpRequest();
request.open('GET', base + id, true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
const data = JSON.parse(this.response);
// console.log(data);
this.setState({data:data})
return data;
} else {
console.log('We reached our target server, but it returned an error!');
this.setState({error:'We reached our target server, but it returned an error!''})
}
};
request.onerror = function() {
console.log('There was a connection error of some sort');
this.setState({error:'There was a connection error of some sort'})
};
request.send();
}