🏅 The goal of this step is to retrieve a list of giphy images based on the query typed in the query input field from Step 2. We'll do this by using the Fetch API and ES6 Promises to retrieve the data from the Giphy API, and then store the data in app state.
As always, if you run into trouble with the tasks or exercises, you can take a peek at the final source code.
Help! I didn't finish the previous step! 🚨
If you didn't successfully complete the previous step, you can jump right in by copying the step.
Complete the setup instructions if you have not yet followed them.
Re-run the setup script, but use the previous step as a starting point:
npm run setup -- src/02-query-field
This will also back up your src/workshop
folder, saving your work.
Now restart the app:
npm start
After some initial compiling, a new browser window should open up at http://localhost:3000/, and you should be able to continue on with the tasks below.
Concepts | Tasks | Exercises | Elaboration & Feedback | Resources
- Making API calls with the
useEffect
hook - Using Promises &
async
/await
- Maintaining app state with the
useState
hook
Import the getResults
API helper along with useEffect
from React. Then call getResults()
within useEffect()
, passing in the value of the input field:
import React, { useState, useEffect } from 'react'
import { getResults } from './api'
// 👆🏾 new imports
const App = () => {
const [inputValue, setInputValue] = useState('')
// 👇🏾 call API w/ useEffect
useEffect(() => {
getResults({ searchQuery: inputValue })
}, [inputValue])
return (
<main>
<h1>Giphy Search!</h1>
<form>
<input
type="search"
placeholder="Search Giphy"
value={inputValue}
onChange={(e) => {
setInputValue(e.target.value)
}}
/>
</form>
</main>
)
}
export default App
NOTE: Be sure to import
useEffect
from thereact
package.
Check the Network panel of your Developer Tools to see that it is making an API call for every character typed within the query input field. The path to interactivity has begun.
In order to render the giphy images we need to store the results in state, once again leveraging useState
:
const [inputValue, setInputValue] = useState('')
const [results, setResults] = useState([])
// 👆🏾 new state variable to contain the search results
useEffect(() => {
// resolve the promise to get the results 👇🏾
getResults({ searchQuery: inputValue }).then((apiResponse) =>
setResults(apiResponse.results),
)
}, [inputValue])
// 👇🏾 logging the results for now
console.log({ inputValue, results })
If you prefer to use async
functions over Promises, you can do that too:
useEffect(() => {
const fetchResults = async () => {
// add async 👆🏾
try {
// 👆🏾 try above, 👇🏾 await below
const apiResponse = await getResults({ searchQuery: inputValue })
setResults(apiResponse.results)
} catch (err) {
console.error(err)
}
}
fetchResults()
}, [inputValue])
console.log({ inputValue, results })
- Type in different search queries and verify the results by digging into the log and navigating to URLs
- Take a look at
api.js
and see what the API helper does, particularly the other search filters it supports- Pass in hard-coded values for the other search filters to
getResults()
and see how the logged data changes
- Pass in hard-coded values for the other search filters to
After you're done with the exercise and before jumping to the next step, please fill out the elaboration & feedback form. It will help seal in what you've learned.
Go to Step 4 - Lists.
- Using the Effect Hook
- Fetch API & Github's
fetch
polyfill
Got questions? Need further clarification? Feel free to post a question in Ben Ilegbodu's AMA!