异步xmlhttp请求中的反应

时间:2017-08-15 21:35:55

标签: javascript reactjs

我正在尝试在反应中实现异步XMLHttpRequest。 这是我的尝试:

var xhr = new XMLHttpRequest();
var json_obj, status = false;
xhr.open("GET", "https://jsonplaceholder.typicode.com/photos/", true);
xhr.onload = function (e) {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      json_obj = xhr.responseText;
      status = true;
    } else {
      console.error(xhr.statusText);
    }
  }
};
xhr.onerror = function (e) {
  console.error(xhr.statusText);
};
xhr.send(null);

class Welcome extends React.Component {
  render() {
    return (
      <div>
          <img src= {status ?  json_obj[0].url : 'loading...'}></img>
      </div>
    );
  }
}
ReactDOM.render(
   <Welcome/>,
   document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

我一直在考虑添加监听器,但我不知道该怎么做。

总体而言,我在异步XMLHttpRequest加载并返回值后遇到更新问题。

4 个答案:

答案 0 :(得分:3)

使用组件的生命周期加载数据,然后异步设置状态。您还需要在返回给您的数据上使用JSON.parse。

class Welcome extends React.Component {
  state = {}

  componentDidMount() {
    var xhr = new XMLHttpRequest();
    var json_obj, status = false;
    xhr.open("GET", "https://jsonplaceholder.typicode.com/photos/", true);
    xhr.onload = function (e) {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          var json_obj = JSON.parse(xhr.responseText);
          status = true;
          this.setState({ json_obj });
        } else {
          console.error(xhr.statusText);
        }
      }
    }.bind(this);
    xhr.onerror = function (e) {
      console.error(xhr.statusText);
    };
    xhr.send(null);
  }

  render() {
    return (
      <div>
          <img src= {this.state.json_obj ?  this.state.json_obj[0].url : 'loading...'}></img>
      </div>
    );
  }
}
ReactDOM.render(
   <Welcome/>,
   document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

答案 1 :(得分:3)

建议在componentDidMount生命周期方法中进行AJAX调用。

componentDidMount用于副作用。添加事件监听器,AJAX,改变DOM等等。

此外,您应该考虑使用新的VichUploaderBundle

class Welcome extends React.Component {
  constructor() {
    this.state = {
      data: null,
    };
  }

  componentDidMount() {
    fetch('https://jsonplaceholder.typicode.com/photos/').then(res => {
      return res.json()
    }).then(res => {
        this.setState({ data: res});
    }).catch(err);
  }

  render() {
    if (this.state.data) {
      return <img src={this.state.data[0].url}></img>
    }
    else {
      return <div>Loading...</div>
    }
  }
}

答案 2 :(得分:1)

我建议连接到componentDidMount生命周期事件并在那里发出请求。然后,一旦完成,请调用setState以更新将重新呈现组件的状态。如果您需要更多信息,请查看此处的视频:

https://www.youtube.com/watch?v=YpM3YK9Uue0

答案 3 :(得分:1)

您需要在React生命周期内执行ajax请求。最简单的方法是收听componentDidMount,执行ajax请求,然后设置状态。

class Welcome extends React.Component {
  constructor() {
    this.state = {
      data: null,
    };
  }

  componentDidMount() {
    var xhr = new XMLHttpRequest();
    var status = false;
    xhr.open("GET", "https://jsonplaceholder.typicode.com/photos/", true);
    xhr.onload = function (e) {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          this.setState({ data: xhr.responseText });
          status = true;
        } else {
          console.error(xhr.statusText);
        }
      }
    };
    xhr.onerror = function (e) {
      console.error(xhr.statusText);
    };
    xhr.send(null);
  }

  render() {
    if (this.state.data) {
      return <img src={this.state.data[0].url}></img>
    }
    else {
      return <div>Loading...</div>
    }
  }
}

您可以在此处详细了解组件生命周期: https://facebook.github.io/react/docs/react-component.html

  • 请注意,此示例无法处理在XHR请求完成之前卸载组件的事实。出于简单的缘故,不包括在这里。