TIL/2021–02–15 & 16
Day 67 and 68: Treehouse Full Stack JavaScript Techdegree
Fetching Data with Fetch API and Axios in React
Fetching Data with the Fetch API
React itself doesn’t have a built-in way to fetch data from a server
There are two ways we can retrieve data from a server
- Fetch
- Axios
Both are promise-based approaches — they use JavaScript promises to handle the results we get back from the server
The state in our app is going to be the gif data we want to display
The gif state now represents a collection of objects that will change and be updated by components
Next, we will set up all of React’s data fetching in Reacts lifcycle method: componentDidMount(){} — when we need to load external data right when the component gets mounted to the DOM — this is a good place to make a request because at this point in the lifecycle the component has a DOM representation
The fetch API uses JavaScript promises to handle the results and promises let you chain methods in a sequential order — something happens after something else is done
Fetching data with axios — Promise based library that is similar to Fetch API
Stronger browser support than fetch
Supports the Promise API
Intercept Request and Response
Transform request and response data
Post data to a server
Protect your app against XSF or CSRF attacks and vulnerabilities
First let’s install axios as a project’s dependency
On the CLI: npm instal — save axios
And now it is in our project’s dependencies
On App.js let’s import axios
import axios from “axios”;
Then let’s delete the code we wrote earlier inside the componentDidMount()
The axios documentation contains all the available config options for performing a request
https://github.com/axios/axios
We can copy this example snippet and customize it from react
The get method performs the request
Then the chained then and catch methods also work exactly as the on in fetch
The function in then gets executed once the get request gets fulfilled and catch will handle any errors
Unlike fetch, axios automatically gets the response in JSON format we get to skip that step and just worry about updating state
If we console log the response
We automatically get the json format of the data/promise retrieved from axios.get(api)
So from this first then method we can already set the state to the data
— -
Displaying the data
To display each gif we have to map each of the gif objects to a gif component
On GifList.js
And on Gif.js
It works!
But we will get an error regarding the key since we need to add a key whenever we map over something in React so react can uniquely identify each object
So let’s add a key property to each object — most APIs returns a unique key id and we can use those
And it works!
— — — -
Building a search feature
On App.js create a function for performing a search
Remove the axios get request from componentDidMount() and add it to the performSearch() function — don’t forget to make the link a template literal so it can be dynamic
The new endpoint offers several parameters we can use to search query term or phrase, limit the number of results returned, offset the results and more
Now the parameter we need in our URL is the q parameter — and as you can see there is already a q parameter and a value in our URL — but the value should be dynamic. It is currently static — it should be the text a user types in the search results
Then on the SearchForm tag we can add the onSearch function as a prop
And on SearchForm.js
On the handleSubmit
And on GifList
And on Gif
And once we search for cat
It works!
— — -
Displaying search results
In our app the search text state is local to the searchForm component — the type of value of our input isnt really part of our application state
We can also use a ref to access the value of the input field
In react, refs allow you to reference or get direct access to the DOM element
Let’s convert the input form’s searchText state into a ref instead — much more recommended in using in bigger applications — less bugs
This.query = input: this is basically putting a reference to the input on the searchForm class.
The ref callback is immediately executed immediately after the component is mounted to the DOM. When the input is rendered to the page it returns a reference to this input which you can access with this.query
And it would work just the same with less code!
Now let’s make our app display a default list of gifs when it first loads
And we can do this by providing the performSearch function a default query parameter
performSearch = (query = “cats”) => {
And then call performSearch on the componentDidMount lifecycle method
And it works! It displays a list of cat gifs as soon as the app loads
Now what if no gifs are returned? Let’s say we type adasdasd on the search
We can render another component when there are no matches
NoGifs
And then on GifList we can have an if statement
But there is one small glitch we should fix, whenever the app loads, we see a quick view of the NoGifs component
This happens because the initial value of the gif state is an empty array — so in the short moment the data is being fetched, there are 0 results
To fix this we can initialize a loading state
So, once we do setState we change the value of the loading state to true since it has been loaded then, let’s adjust our if statement
Or we can do a loading indicator