Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed Data Fetching in React!
You have completed Data Fetching in React!
Preview
In this video, we'll use Giphy API's search endpoint to add a Gif search feature to our app.
Search Endpoint
https://api.giphy.com/v1/gifs/search?api_key=<ENTER YOUR API KEY HERE>&q=${query}&limit=24&rating=g
Resources
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
The GIPHY API also provides
a Search Endpoint that let you search for
0:00
GIFs using a word or phrase.
0:05
So, in this video, we'll use this endpoint
to create a search feature for our app.
0:07
Users will be able to search for
GIFs by typing into this text field.
0:13
And the search results will be returned
and displayed in the list of GIFs when
0:19
you hit the enter key, or
click the search icon, next to the field.
0:24
So first, in the App component,
we need to change the URL in the get
0:29
method to the endpoint that
returns a search query.
0:34
I'll copy this URL from the GIPHY docs and
replace the trending endpoint.
0:39
This endpoint offers several parameters
you can use to search query, a term,
0:49
or phrase, limit the number of results
returned, offset the results, and more.
0:54
Now the parameter we need in our
URL is the q or query parameter.
1:01
So in our URL right after the question
mark, we'll add a q parameter.
1:06
The value of the q parameter
needs to be dynamic.
1:13
So q should be equal to the text
a user typed into the search field.
1:17
So, let's create a new state called query
and the function to update it as setQuery.
1:23
We'll set it equal to useState and set the
initial value as an empty string for now.
1:30
Now in the get method, we'll change the
URL from a string to a template literal,
1:39
so that we're able to embed the value of
query into the URL using interpolation.
1:45
So after the equal sign,
add a dollar symbol,
1:52
curly braces, and query.
1:57
So right now, we're only fetching the data
when the component is mounted to the DOM,
2:00
since we provided the useEffect hook an
empty dependency array.
2:06
But we want the data to be fetched
each time the query state changes.
2:11
So to do that,
we'll add query to the dependency array.
2:16
So now we need to create a way for
2:21
the SearchForm component to be
able to update the query state.
2:24
We'll do that by creating a function
called handleQueryChange.
2:28
This function will accept
a searchText value.
2:36
And in the function it will update
the query state with setQuery and
2:39
passing it the searchText value.
2:44
In App's return method,
let's give the SearchForm component
2:49
the prop changeQuery,
passing it handleQueryChange.
2:54
This passes the handleQueryChange
function to the SearchForm component and
2:59
invokes it whenever
the changeQuery prop is called.
3:04
So let's save and have a look at
the SearchForm component in SearchForm.js.
3:08
This component has a searchText state
that's specific to the component.
3:15
It gets updated in this onChange event,
3:21
with the text user's type
into the input field.
3:23
And the handleSubmit function is
called when the form is submitted,
3:29
here in the onSubmit
handler given to the form.
3:33
Currently, handleSubmit just
calls preventDefault and
3:38
resets the input field on submit
with currentTarget.reset.
3:42
So inside this function is where
we'll need to invoke the changeQuery
3:47
function that updates the query state,
3:52
which invokes the data to be
fetched by the useEffect hook.
3:54
We'll call the function
with props.changeQuery
3:59
Remember, changeQuery takes one argument,
the searchQuery.
4:05
But how do we pass the query
value back up to the function?
4:11
Well, we do so
by passing the searchText state to
4:15
the changeQuery function callback,
with searchText.
4:19
Let's save and
test our app in the browser.
4:26
In the search field, I'll type cats,
hit Enter, and it works.
4:29
The query returns 24 cat GIFs.
4:35
Now, it doesn't seem obvious, but our code
is easily subjected to race conditions.
4:39
In data fetching, race condition
is when multiple data is fetched,
4:45
but the data doesn't return in the order
you expect it slash want it to.
4:50
Since data fetching uses promises, we
don't know when the data will be returned.
4:56
If multiple fetches
happen at the same time,
5:02
we don't know the order
the data will return.
5:04
To make the race condition
more noticeable,
5:08
let's make some changes to
how our data is fetched.
5:11
You don't have to follow along,
I'm only making these changes so
5:14
you can visually see
race condition in action.
5:18
Right now our useEffect hook will
fetch the data right when the query
5:22
state changes.
5:26
Let's have useEffect wait a random
period of up to ten seconds per
5:27
request by using the setTimeout method.
5:32
The setTimeout method executes a piece
of code once the timer expires.
5:37
We'll pass a setTimeout,
an arrow function, and
5:43
move the data fetching code inside it.
5:46
The second parameter the setTimeout
method takes is the amount
5:56
of time in milliseconds to wait
before running the block of code.
6:00
So we'll pass Math.ceil,
parentheses Math.Random,
6:05
times 10,000 or 10 seconds.
6:11
So now our useEffect hook will fetch
the data after a random period of up to
6:17
10 seconds.
6:21
We're doing this because GIPHYs API is
really good at giving back our data
6:24
quickly, so we added a random wait
period in between multiple fetches so
6:29
we can see the race condition in action.
6:34
Let's save and head over to the browser.
6:37
All right, to see an example of race
condition, let's fetch multiple GIFs.
6:41
We'll search A, B, then C.
6:46
We expect to end up with
GIFs of the letter C, but
6:50
we actually ended up with
GIFs of the letter A.
6:54
If you did end up with GIFs
of the letter C, no worries.
6:58
Sometimes our fetches come back
in the order we expected, but
7:02
that isn't 100% guaranteed.
7:06
So to ensure our app doesn't
suffer from race conditions,
7:09
let's go back to App.js and
make some changes to our useEffect hook.
7:13
We can keep track of which fetch is
the latest by using useEffects cleanup
7:19
function and adding a Boolean
variable that equals to true before
7:24
the data is fetched, and equal to
false when another fetch is called.
7:28
Let me show you how to implement this.
7:34
So, first, we'll declare a variable
called activeFetch at the top of
7:37
our useEffect hook and
set it equal to true.
7:42
This variable will keep track of
which data fetch is the latest.
7:46
So now, when we fetch the data,
7:53
we only want the GIF state to
update if this is the latest fetch.
7:55
So in the then method
where we call setGifs,
8:01
add an if statement that checks
if activeFetch is true.
8:04
If so,
update the GIF state with the GIF data.
8:10
Now to set activeFetch to false
when another fetch is called,
8:15
we'll use useEffect
hooks cleanup function.
8:20
As you may remember, the setup function
can return a cleanup function that
8:24
will always run before
the next setup function.
8:29
We'll type return and an arrow function.
8:33
Before fetching the next set of GIFs,
we want to set the activeFetch
8:37
variable to false, so
that whenever the previous fetch returns,
8:41
it will not change the GIF state
because of our if statement here.
8:46
I know this can be a little confusing,
so let's run through what we just wrote.
8:52
Whenever the query state changes,
the set up function creates a local
8:57
variable called activeFetch and
sets it to true.
9:02
Then we fetch the data,
when the query changes again,
9:07
the previous local activeFetch
variable is set to false and
9:11
a new local activeFetch variable is
declared, and a new fetch is called.
9:15
The GIF state will only update
when the latest data is fetched,
9:22
meaning activeFetch is set to true.
9:27
All right, let's save this and
see it in action.
9:30
In the browser let's search a,
b, and c, and
9:34
we only see GIFs of the letter c, great.
9:39
Let's go back to our useEffect hook and
remove the setTimeout method.
9:44
We only added this to make the race
condition more noticeable.
9:48
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up