scrimba
Frontend Career Path
Advanced React
React Router
Quick update to our fetching code
Go Pro!Bootcamp

Bootcamp

Study group

Collaborate with peers in your dedicated #study-group channel.

Code reviews

Submit projects for review using the /review command in your #code-reviews channel

Quick update to our fetching code
AboutCommentsNotes
Quick update to our fetching code
Expand for more info
pages
Vans
Vans.jsx
run
preview
console
import React from "react"
import { Link, useSearchParams } from "react-router-dom"

export default function Vans() {
const [searchParams, setSearchParams] = useSearchParams()
const [vans, setVans] = React.useState([])

const typeFilter = searchParams.get("type")

React.useEffect(() => {
fetch("/api/vans")
.then(res => res.json())
.then(data => setVans(data.vans))
}, [])

const displayedVans = typeFilter
? vans.filter(van => van.type === typeFilter)
: vans

const vanElements = displayedVans.map(van => (
<div key={van.id} className="van-tile">
<Link
to={van.id}
state={{
search: `?${searchParams.toString()}`,
type: typeFilter
}}
>
<img src={van.imageUrl} />
<div className="van-info">
<h3>{van.name}</h3>
<p>${van.price}<span>/day</span></p>
</div>
<i className={`van-type ${van.type} selected`}>{van.type}</i>
</Link>
</div>
))

function handleFilterChange(key, value) {
setSearchParams(prevParams => {
if (value === null) {
prevParams.delete(key)
} else {
prevParams.set(key, value)
}
return prevParams
})
}

return (
<div className="van-list-container">
<h1>Explore our van options</h1>
<div className="van-list-filter-buttons">
<button
onClick={() => handleFilterChange("type", "simple")}
className={
`van-type simple
${typeFilter === "simple" ? "selected" : ""}`
}
>Simple</button>
<button
onClick={() => handleFilterChange("type", "luxury")}
className={
`van-type luxury
${typeFilter === "luxury" ? "selected" : ""}`
}
>Luxury</button>
<button
onClick={() => handleFilterChange("type", "rugged")}
className={
`van-type rugged
${typeFilter === "rugged" ? "selected" : ""}`
}
>Rugged</button>

{typeFilter ? (
<button
onClick={() => handleFilterChange("type", null)}
className="van-type clear-filters"
>Clear filter</button>
) : null}

</div>
<div className="van-list">
{vanElements}
</div>
</div>
)
}
Console
!
TypeError: Cannot read properties of undefined (reading 'map')
,
!
TypeError: Cannot read properties of undefined (reading 'map')
,
!
"The above error occurred in the <Vans> component: at Vans (https://cw1.scrimba.com/pages/Vans/Vans:5:43) at RenderedRoute (https://ga.jspm.io/npm:react-router@6.4.3/dist/index.js:11:8346) at Outlet (https://ga.jspm.io/npm:react-router@6.4.3/dist/index.js:11:13986) at main at div at Layout at RenderedRoute (https://ga.jspm.io/npm:react-router@6.4.3/dist/index.js:11:8346) at Routes (https://ga.jspm.io/npm:react-router@6.4.3/dist/index.js:11:15196) at Router (https://ga.jspm.io/npm:react-router@6.4.3/dist/index.js:11:14234) at BrowserRouter (https://ga.jspm.io/npm:react-router-dom@6.4.3/dist/index.js:11:3422) at App Consider adding an error boundary to your tree to customize error handling behavior. Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."
,
!
TypeError: Cannot read properties of undefined (reading 'map')
,
/vans
-2:57