We've been able to greatly reduce the scope of the top-level App
by breaking it down into several components. However, it still directly makes the API call in order to maintain the app-level state. App
is just an orchestrator, it shouldn't really do any work.
🏅 The goal of this step is to learn how to create our own custom hooks composed of the base hooks like useState
& useEffect
. This allows us to extract component logic into reusable (and testable) functions.
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/08-search-focus
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
- Creating (async) custom hooks
Create a new file called src/workshop/useGiphy.js
which will contain our custom hook that will take in search parameters, make an API call and return results:
import { useState, useEffect } from 'react'
import { getResults } from './api' // 👈🏾 bring over API import
const useGiphy = () => {
return null
}
export default useGiphy
A custom hook is a normal JavaScript function whose name must start with use*
and may call other hooks, like useState
& useEffect
.
Copy over all the hooks-related code from App.js
into useGiphy.js
:
const useGiphy = () => {
const [searchParams, setSearchParams] = useState({})
const [results, setResults] = useState([])
useEffect(() => {
const fetchResults = async () => {
try {
const apiResponse = await getResults(searchParams)
setResults(apiResponse.results)
} catch (err) {
console.error(err)
}
}
fetchResults()
}, [searchParams])
return [results, setSearchParams]
}
Now useGiphy()
can easily be used w/in other components because all of the state management and side-effect API logic have been abstracted away.
- Finish the feature by calling
useGiphy()
back inApp
- Compare the current version of
App.js
with the Step 5App.js
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 10 - Loading States.
Got questions? Need further clarification? Feel free to post a question in Ben Ilegbodu's AMA!