---
id: faq-ajax
title: AJAX and APIs
permalink: docs/faq-ajax.html
layout: docs
category: FAQ
---
### How can I make an AJAX call? {#how-can-i-make-an-ajax-call}
You can use any AJAX library you like with React. Some popular ones are [Axios ](https://github.com/axios/axios ), [jQuery AJAX ](https://api.jquery.com/jQuery.ajax/ ), and the browser built-in [window.fetch ](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API ).
### Where in the component lifecycle should I make an AJAX call? {#where-in-the-component-lifecycle-should-i-make-an-ajax-call}
You should populate data with AJAX calls in the [`componentDidMount` ](/docs/react-component.html#mounting ) lifecycle method. This is so you can use `setState` to update your component when the data is retrieved.
### Example: Using AJAX results to set local state {#example-using-ajax-results-to-set-local-state}
The component below demonstrates how to make an AJAX call in `componentDidMount` to populate local component state.
The example API returns a JSON object like this:
```
{
"items": [
{ "id": 1, "name": "Apples", "price": "$2" },
{ "id": 2, "name": "Peaches", "price": "$5" }
]
}
```
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: []
};
}
componentDidMount() {
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: true,
error
});
}
)
}
render() {
const { error, isLoaded, items } = this.state;
if (error) {
return < div > Error: {error.message}< / div > ;
} else if (!isLoaded) {
return < div > Loading...< / div > ;
} else {
return (
< ul >
{items.map(item => (
< li key = {item.id} >
{item.name} {item.price}
< / li >
))}
< / ul >
);
}
}
}
```
Here is the equivalent with [Hooks ](https://reactjs.org/docs/hooks-intro.html ):
```js
function MyComponent() {
const [error, setError] = useState(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState([]);
// Note: the empty deps array [] means
// this useEffect will run once
// similar to componentDidMount()
useEffect(() => {
fetch("https://api.example.com/items")
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
setIsLoaded(true);
setError(error);
}
)
}, [])
if (error) {
return < div > Error: {error.message}< / div > ;
} else if (!isLoaded) {
return < div > Loading...< / div > ;
} else {
return (
< ul >
{items.map(item => (
< li key = {item.id} >
{item.name} {item.price}
< / li >
))}
< / ul >
);
}
}
```