I am trying to implement asynchronous XMLHttpRequest in react. Here is my attempt:
It is recommended to make AJAX calls in the componentDidMount
lifecycle method.
componentDidMount
is for side effects. Adding event listeners, AJAX, mutating the DOM, etc.
Also, you should consider using the new fetch API.
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>
}
}
}
I'd recommend hooking to the componentDidMount lifecycle event and make your request there. Then, once it has finished, call setState
to update the state which will re-render your component. Check out the video here if you need more info:
https://www.youtube.com/watch?v=YpM3YK9Uue0
Use the component's lifecycle to load the data and then set the state asynchronously. You will also need to use JSON.parse on the data returned to you.
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>
You need to perform the ajax request within the React lifecycle. The easiest way is to listen to componentDidMount
, perform your ajax request, and then set the state.
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>
}
}
}
You can read more about the component lifecycle here: https://facebook.github.io/react/docs/react-component.html