在另一个函数

时间:2017-01-21 21:33:54

标签: javascript json reactjs

我有一个名为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

2 个答案:

答案 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();
}