In this article, we are going to learn how to use Axios with React to make API requests and also how to handle the response. We’d learn this by building a simple blog using a fake API server. What is Axios? Axios is a JavaScript library built for making HTTP requests from NodeJS or the browser. These include POST, GET, and many other forms of requests. It can be be used in vanilla Javascript as well as many other frameworks but our use-case today is . React Communicating with before was usually done with the fetch API. Axios doesn’t replace this but only makes the communication easier. It also has better error handling, easy header configurations and the readability of code is improved. APIs The features of Axios according to the NPM documentation are:Make from the HTTP requests from node.js Automatic transforms for JSON dataTransform request and response data XMLHttpRequests browserMake You can get more features in the npm documentation. Blog Project We’d be using a popular public API – . We can get a list of posts by hitting the /posts endpoint, edit and delete posts by /post/id and so on. You can check the site to see how to use their endpoints. http://jsonplaceholder.typicode.com/ Create a project folder and change directory To use Axios in React, you’d need to install the package. Before you do that, we need our project folder. Quickly set up a project using create-react-app. Install the package – npm install -g create-react-app Create the project – create-react-app axios-with-react Change directory – cd axios-with-react. Start server – npm run start Go to the browser and enter , localhost:3000 you’d seeproject which the package sets for us. Install Axios Library npm axios install --save Making Requests with Axios Axios handles request methods such as , , , , , etc. We’d be seeing some of the actions in our project. POST GET PUT DELETE PATCH GET Request Change the contents of App.js to the following React ; ; axios ; { state = { : , : , : , : [] } componentDidMount() { axios.get( ) .then( { newData = res.data.slice( , ); .setState({ : newData[newData.length - ].id + , : newData }, () => .log( .state.id)) .log(newData) }) .catch( .log( + err)) } render() { ( <h1>Simple blog with React</h1> <div className='AddArticle'> <b>id of article: </b> <input type='number' value={this.state.id} /> <form> <input type='text' placeholder='Title' value={this.state.title} /> <textarea placeholder='Enter Body' value={this.state.body}> </textarea> <input type='submit' value='Add/Update Post'/> </form> </div> { this.state.data.length === 0 ? <p>Loading Posts...</p> : this.state.data.map((post, index) => ( <article key={index}> <h2>{index + 1}. {post.title}</h2> <p>{post.body.substr(0, 100)}...</p> <button className='delete'>Delete</button> <button className='edit'>Edit</button> </article> )) } </div> ) } } export default App; import from 'react' import './App.css' import from 'axios' . class App extends React Component id '' title '' body '' data 'https://jsonplaceholder.typicode.com/posts' => res let 0 5 this id 1 1 data console this console => err console "Couldn't fetch data. Error: " return < = > div className 'ArticleContainer' is the safest stage in React components for making API requests. It is a cycle in a component’s life which ensures that the elements have been mounted to the DOM. Imagine making a request which would take a couple of time. It may keep our DOM empty until the request is completed. componentDidMount First, we have Loading posts showing on the screen until the data is fetched. Check the console of your browser, you either get an error or the response from the endpoint we hit. From the response, we understand the structure and know-how to place the data on our frontend. Notice we have only 5 results, that’s because we sliced the array. We are supposed to get over 100 results. Let’s add our CSS to see our beautiful frontend. Copy the following to App.css * { : border-box; } { : ; : auto; : ; } { : flex; : column; : ; } , { : ; : ; : solid ; : ; : ; } { : ; : greenyellow; : none; : pointer; } { : center; } { : ; : solid ; : auto ; : ; } { : orange; : ; : ; } { : ; : ; : none; : ; : pointer; } { : red;} { :green;} { : orange;} box-sizing .ArticleContainer width 500px margin 0 margin-top 20px .AddArticle display flex-direction width 100% .AddArticle input .AddArticle textarea width 100% border-radius 5px border 1px #ddd margin 5px 0 padding 5px .AddArticle input [type='submit'] padding 5px background-color border cursor h1 text-align article padding 10px border 1px #ddd margin 10px 20px width 100% article h2 color font-size 30px margin 5px 0 article button width 50px margin 0 5px border padding 5px cursor article .delete color article .edit color article .cancel color We should have this; We have five posts each with their id. The new article will have an id of 6. We can add more posts by making a post request to the server. POST Request We have the endpoint which allows us to create posts. Note that, as said on their website, the data would not be created on their server. It will only be faked as you’ll get a positive response for illustration purposes. https://jsonplaceholder.typicode.com/posts We have a button which handles creation and edition of posts – Add/Update Post button. I configured it this way so that we do not have to route to any other page to see all requests in action. A method will be called by the button which will either add or update a post. In your above, add the following methods immediately after the state declaration code ... changeId = { id = e.target.value; .setState({ : id }) } changeTitle = { title = e.target.value; .setState({ : title }) } changeBody = { body = e.target.value; .setState({ : body }) } addOrUpdatePost = { e.preventDefault(); ( .state.title === || .state.body === || .state.id === ) { alert( ); ; } ( .state.id > .state.data.length + ) { alert( ); } { ( .state.data[ .state.id - ] !== ) { } { axios.post( , { : .state.id + , : .state.title, : .state.body }) .then( { .log(res); newPost = res.data; newData = [...this.state.data, newPost]; .setState({ : .state.id + , : , : , : newData }); }) .catch( .log(err)); } } ... => e let this id => e let this title => e let this body => e if this '' this '' this '' 'No field should be empty' return else if this this 1 'Please use the next id' else if this this 1 undefined // update the post else // new post "https://jsonplaceholder.typicode.com/posts" id this 1 title this body this => res console let let this id this 1 title '' body '' data => err console First, we have three methods that update the id, title, and body of the state respectively when called upon. Next, we check to see if the states are empty which would result in an alert box, stating that “No field should be empty”We also confirm that the current id has either been used or just greater than the highest id with 1. If it isn’t, we have an alert box which says “Please use the next id”A decision has to be made if a new post is to be created or a previous post is to be updated. We check if the id exists by . If it returns undefined, it means the id doesn’t exist so we can create a new post there. this.state.data[this.state.id - 1] !== undefined We’d look at the update process soon. Let’s add these methods to our elements. Update your code to this ... render() { ( <h1>Simple blog with React</h1> <div className='AddArticle'> <b>id of article: </b> <input type='number' onChange={this.changeId} value={this.state.id} /> <form> <input onChange={this.changeTitle} type='text' placeholder='Title' value={this.state.title} /> <textarea onChange={this.changeBody} placeholder='Enter Body' value={this.state.body}> </textarea> <input onClick={this.addOrUpdatePost} type='submit' value='Add/Update Post'/> </form> </div> { this.state.data.length === 0 ? <p>Loading Posts...</p> : this.state.data.map((post, index) => ( <article key={index}> <h2>{index + 1}. {post.title}</h2> <p>{post.body.substr(0, 100)}...</p> <button onClick={() => this.deletePost(index)} className='delete'>Delete</button> <button onClick={() => this.editPost(index, post.title, post.body)} className='edit'>Edit</button> </article> )) } </div> ) } ... return < = > div className 'ArticleContainer' When the add button is clicked, we use the post method to send our new post through the API. Remember that it’s a fake live server, so it only returns a reponse which contains our new post as an object with a statusText of created. We add new data to the previous data and update the state. When the component is re-rendered, our post will be the sixth post on the list. Here is our response to the console. Notice the and in our code above. It allows us to edit or delete an individual posts. We’d come to that shortly. editPost deletePostmethod Update Request Our API gives us endpoints which we could use to update resources. For example, we could update the post with id 1, by hitting this endpoint – https://jsonplaceholder.typicode.com/posts/1 Let’s add the e . Add the following immediately after the ditPostmethod changeBodymethod ... editPost = { .setState({ : postIndex + , : title, : body }) } ... ( ) => postIndex, title, body this id 1 title body The function takes the , title and body argument and resets the state. Remember that in setting the state, the input fields reflect the values. Also, remember that our button handles add and update. postIndex Since the id has been used before, would not return undefined. this.state.data[this.state.id - 1] Delete Request We can also hit endpoints of posts and delete a post by their id. We already have the delete button so let’s add the method which it calls on clicking. Add the following before componentDidMount deletePost = { axios.delete( ) .then( { newData = [...this.state.data]; newData.splice(postIndex, ); .setState({ : newData.length + , : , : , : newData }) .log(res) }) .catch( .log(err)); } => postIndex `https://jsonplaceholder.typicode.com/posts/ ` ${postIndex} => res let 1 this id 1 title '' body '' data console => err console The post is deleted when the delete method is called. The method takes the index, searches for it in our data and removes it thereby updating the state. The whole code for the project (except the CSS); React ; ; axios ; { state = { : , : , : , : [] } changeId = { id = e.target.value; .setState({ : id }) } changeTitle = { title = e.target.value; .setState({ : title }) } changeBody = { body = e.target.value; .setState({ : body }) } editPost = { .setState({ : postIndex + , : title, : body }) } addOrUpdatePost = { e.preventDefault(); ( .state.title === || .state.body === || .state.id === ) { alert( ); ; } ( .state.id > .state.data.length + ) { alert( ); } { ( .state.data[ .state.id - ] !== ) { axios.put( , { : .state.id , : .state.title, : .state.body }).then( { updatedData = [...this.state.data]; updatedData[ .state.id - ] = res.data; .setState({ : updatedData.length + , : , : , : updatedData }) .log(res) }) .catch( .log(err)); } { axios.post( , { : .state.id + , : .state.title, : .state.body }) .then( { .log(res); newPost = res.data; newData = [...this.state.data, newPost]; .setState({ : .state.id + , : , : , : newData }); }) .catch( .log(err)); } } } deletePost = { axios.delete( ) .then( { newData = [...this.state.data]; newData.splice(postIndex, ); .setState({ : newData.length + , : , : , : newData }) .log(res) }) .catch( .log(err)); } componentDidMount() { axios.get( ) .then( { newData = res.data.slice( , ); .setState({ : newData[newData.length - ].id + , : newData }, () => .log( .state.id)) .log(newData) }) .catch( .log( + err)) } render() { ( <h1>Simple blog with React</h1> <div className='AddArticle'> <b>id of article: </b> <input type='number' onChange={this.changeId} value={this.state.id} /> <form> <input onChange={this.changeTitle} type='text' placeholder='Title' value={this.state.title} /> <textarea onChange={this.changeBody} placeholder='Enter Body' value={this.state.body}> </textarea> <input onClick={this.addOrUpdatePost} type='submit' value='Add/Update Post'/> </form> </div> { this.state.data.length === 0 ? <p>Loading Posts...</p> : this.state.data.map((post, index) => ( <article key={index}> <h2>{index + 1}. {post.title}</h2> <p>{post.body.substr(0, 100)}...</p> <button onClick={() => this.deletePost(index)} className='delete'>Delete</button> <button onClick={() => this.editPost(index, post.title, post.body)} className='edit'>Edit</button> </article> )) } </div> ) } } export default App; import from 'react' import './App.css' import from 'axios' . class App extends React Component id '' title '' body '' data => e let this id => e let this title => e let this body ( ) => postIndex, title, body this id 1 title body => e if this '' this '' this '' 'No field should be empty' return else if this this 1 'Please use the next id' else if this this 1 undefined `https://jsonplaceholder.typicode.com/posts/ ` ${ .state.id} this id this title this body this => res let this 1 this id 1 title '' body '' data console => err console else "https://jsonplaceholder.typicode.com/posts" id this 1 title this body this => res console let let this id this 1 title '' body '' data => err console => postIndex `https://jsonplaceholder.typicode.com/posts/ ` ${postIndex} => res let 1 this id 1 title '' body '' data console => err console 'https://jsonplaceholder.typicode.com/posts' => res let 0 5 this id 1 1 data console this console => err console "Couldn't fetch data. Error: " return < = > div className 'ArticleContainer' We were working on a demo server, that’s why I had to manually update all properties of the state every time we make a request. If we were using a server which gave us access to manipulate the data, all we’d have to do is make our requests and update the state to the current data. We wouldn’t have to filter by the index of the post. Check out the for more information about Axios. npm documentation I hope with this article, you have seen how easy it is making requests with Axios. You can access CodeSource . here