🏅 The goal of this step is to practice transforming lists of data into lists of components which can be included in JSX. We'll take the results
data we have in state in convert it to visible UI!
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/03-api
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
- Rendering dynamic lists of data
- Handling special
key
prop - Conditionally rendering components
We need to convert the array of results into an array of components so that we can render the giphy images. There are several ways, but the most common approach is to use Array.prototype.map
:
return (
<main>
<h1>Giphy Search!</h1>
<form>
<input
type="search"
placeholder="Search Giphy"
value={inputValue}
onChange={(e) => {
setInputValue(e.target.value)
}}
/>
</form>
<section className="callout primary">
{results.map((item) => (
<video
key={item.id} // 👈🏾 special `key` prop
src={item.previewUrl}
alt={item.title}
loop
autoPlay
/>
))}
</section>
</main>
)
NOTE: Be sure to include the
key
prop on the<li>
elements.
We need to only render the <section>
when there are results. There are a number of different ways to conditionally render JSX. The most common approach is:
return (
<main>
<h1>Giphy Search!</h1>
<form>
<input
type="search"
placeholder="Search Giphy"
value={inputValue}
onChange={(e) => {
setInputValue(e.target.value)
}}
/>
</form>
{results.length > 0 && ( // 👈🏾 inline if with &&
<section className="callout primary">
{results.map((item) => (
<video
key={item.id}
src={item.previewUrl}
alt={item.title}
loop
autoPlay
/>
))}
</section>
)}
</main>
)
Let's add some additional markup and classes around the <img />
so we can include the giphy title:
{
results.length > 0 && (
<section className="callout primary">
{results.map((item) => (
<section
key={item.id} // 👈🏾 `key` moves here
className="card"
style={{
width: '300px',
display: 'inline-block',
marginRight: '16px',
}}
>
<video src={item.previewUrl} alt={item.title} loop autoPlay />
<section className="card-section">
<h5>{item.title}</h5>
</section>
</section>
))}
</section>
)
}
NOTE: Be sure to move the
key
prop to the containing<section>
within the.map()
.
- Make the displayed title (
item.title
) link to the Giphy URL (item.url
) - Display the Giphy Rating (
item.rating
) - Add a
<select>
to the search form to change the number of Giphy images displayed (thelimit
search param)- Map over a
const LIMITS = [6, 12, 18, 24, 30]
constant to generate the<option value={limit}>
tags within the<select>
- The props should be
<select value={searchLimit} onChange={(e) => { ... }}>
- The default should remain
12
- Map over a
- Open the Developer Tools, on the Elements tab, and monitor how the markup changes when changing limits
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 5 - Form Submit.
Got questions? Need further clarification? Feel free to post a question in Ben Ilegbodu's AMA!