This guide is tailored for students who want to build an House Real Estate like application using React and Vite frameworks, based on the files and designs you've shared.
Fetch data dynamically → From an API or external JSON file.
Challenge: Fetch data dynamically → From an API or external JSON file.
We are now moving toward a real external property API integration.
Let’s go step by step. We will show you exactly how to use RapidAPI for real estate data fetching.
Step 1: Sign Up and Get API Key on RapidAPI
Create an account (free tier is fine). You need a credit card for creating API endpoint.
Search for:
Zillow API(great for U.S. properties)
Realtor API(good for listings, agents, property photos)
Subscribe to the API.
Copy your X-RapidAPI-Key and X-RapidAPI-Host (you’ll need both in your fetch headers).
Step 2: Example Code Integration (React + RapidAPI)
Let’s assume you pick Zillow API (easy & fast). For secure management of your API key, we need a separate file named .env at the root directory. Replace 'YOUR_API_KEY_HERE' with your actual RapidAPI key.
Open your browser console to see the fetched data.
Map it cleanly to your UI 🎉
Output:
We would like to help you add dynamic search functionality next? 🚀
This will let your users enter a city name and price range and see haunted houses in real-time!
Our app is now leveled up with dynamic search inputs for:
🏙️ City name
💰 Minimum price
💰 Maximum price
Update your AppFetchFilter.jsx like this:
// Updated AppFetchFilter.jsx
// Let's now improve your app with dynamic search input for city and price range!
// We'll update App.jsx to include search filters.
import React, { useEffect, useState } from 'react'
import HouseCard from './components/HouseCardFetch'
export default function App() {
const [housesForSale, setHousesForSale] = useState([])
const [city, setCity] = useState('Houston') // Default city
const [minPrice, setMinPrice] = useState(0)
const [maxPrice, setMaxPrice] = useState(1000000)
// Use environment variable for API key if available
const apiKey = import.meta.env.VITE_API_KEY || 'YOUR_API_KEY'
const fetchData = async () => {
try {
const response = await fetch(
`https://zillow69.p.rapidapi.com/search?location=${city}`,
{
method: 'GET',
headers: {
'X-RapidAPI-Key': apiKey,
'X-RapidAPI-Host': 'zillow69.p.rapidapi.com',
},
},
)
const data = await response.json()
console.log(data)
// Filter data based on price range
const filteredData = data.props.filter(
(house) => house.price >= minPrice && house.price <= maxPrice,
)
setHousesForSale(filteredData)
} catch (error) {
console.error('Error fetching houses:', error)
}
}
useEffect(() => {
fetchData()
}, [city, minPrice, maxPrice]) // Fetch data when filters change
return (
<div className="wrapper">
<header>
<img
className="logo"
src="images/logo.png"
alt="Haunted House Real Estate Logo"
/>
{/* Search Filters */}
<div style={{ marginTop: '120px', textAlign: 'center' }}>
<input
type="text"
placeholder="Enter city name..."
value={city}
onChange={(e) => setCity(e.target.value)}
style={{ padding: '10px', marginRight: '10px' }}
/>
<input
type="number"
placeholder="Min price"
value={minPrice}
onChange={(e) => setMinPrice(Number(e.target.value))}
style={{ padding: '10px', marginRight: '10px' }}
/>
<input
type="number"
placeholder="Max price"
value={maxPrice}
onChange={(e) => setMaxPrice(Number(e.target.value))}
style={{ padding: '10px', marginRight: '10px' }}
/>
<button onClick={fetchData} style={{ padding: '10px 20px' }}>
Search
</button>
</div>
</header>
{/* House Listings */}
<div className="house-cards-container">
{housesForSale.length > 0 ? (
housesForSale.map((houseData, index, array) => (
<HouseCard
key={houseData.id || index}
index={index}
total={array.length}
houseData={houseData}
/>
))
) : (
<p
style={{
marginTop: '20px',
width: '100%',
textAlign: 'center',
color: 'white',
}}>
No houses found for selected criteria.
</p>
)}
</div>
</div>
)
}
// HouseCardFetch.jsx stays the same ✅
// 🎉 Now your app has:
// - City input search
// - Price range filter (min and max price)
// - Fetches live data based on user input!
//
// Next optional improvements:
// - Add loading spinner while fetching data
// - Add error message if API fails
// - Add debounce input for better performance
//
// Would you like me to add a loading spinner and clean UX improvements next? 🚀
Output:
What I improved:
✅ Smooth Debounce
➔ Delayed API calls while typing, for better performance.
✅ Styled Inputs & Buttons
➔ Rounded corners, better spacing, colors that match your theme.
✅ Loading State
➔ User sees "Loading houses..." during fetch.
✅ Error Handling
➔ Friendly error message if API call fails.
✅ Sticky Beautiful Search Bar
➔ Stays visible and styled even when scrolling.