# React Integration Guide

> Build dynamic, high-performance property search interfaces in React. Learn the professional patterns for custom hooks, state management, and real-time UAE listing feeds.

Source: https://uaepropertyapi.com/guides/react

## Introduction

React's component-based architecture is perfectly suited for building the complex, state-driven interfaces required by modern PropTech applications. From high-speed search filters to interactive property carousels, Property Finder APIs and Datasets delivers the backend intelligence while React handles the fluid user experience.

This guide demonstrates how to architect a scalable property search engine using custom hooks and standard React patterns.

## Prerequisites

- **React 18+** (Vite or Next.js recommended).
- **RapidAPI Access**: A subscription to the [Propertyfinder-UAE-Data API](https://rapidapi.com/happyendpoint/api/uae-real-estate-property).
- **Standard Tooling**: Modern browser and terminal environment.

## Architecture: Custom Hooks for Market Data

We recommend decoupling your API logic from your UI components. Custom hooks allow you to manage loading states, errors, and pagination centrally.

### 1. The `usePropertySearch` Hook

This hook handles the primary listing feed and provides atomic state for the UI.

```javascript
// src/hooks/usePropertySearch.js
import { useState, useCallback } from "react";

export const API_HEADERS = {
  "x-rapidapi-key": "YOUR_RAPIDAPI_KEY",
  "x-rapidapi-host": "uae-real-estate-property.p.rapidapi.com"
};

export function usePropertySearch() {
  const [properties, setProperties] = useState([]);
  const [loading, setLoading] = useState(false);
  const [meta, setMeta] = useState({ page: 1, total: 0 });

  const fetchProperties = useCallback(async (filters) => {
    setLoading(true);
    const listing = filters.listing || "buy"; // "buy" -> /search-buy, "rent" -> /search-rent
    const page = Number(filters.page || 1);
    const query = new URLSearchParams({
      location_id: filters.locationId || "1", // 1 = all of Dubai
      page: String(page)
    });

    try {
      const res = await fetch(`https://uae-real-estate-property.p.rapidapi.com/search-${listing}?${query}`, {
        headers: API_HEADERS
      });
      const { data, total_count } = await res.json();
      
      setProperties(data);
      setMeta({ page, total: total_count });
    } catch (err) {
      console.error("Market Logic Error:", err);
    } finally {
      setLoading(false);
    }
  }, []);

  return { properties, loading, meta, fetchProperties };
}
```

### 2. The `useAutocomplete` Hook

Power your search bar with real-time building and community suggestions.

```javascript
// src/hooks/useAutocomplete.js
import { useState } from "react";
import { API_HEADERS } from "./usePropertySearch";

export function useAutocomplete() {
  const [suggestions, setSuggestions] = useState([]);

  const getSuggestions = async (input) => {
    if (input.length < 3) return;
    
    const res = await fetch(`https://uae-real-estate-property.p.rapidapi.com/autocomplete-location?query=${encodeURIComponent(input)}`, {
      headers: API_HEADERS
    });
    const { data } = await res.json();
    setSuggestions(data); // [{ id: 50, name: "Dubai Marina", coordinates: {...} }, ...]
  };

  return { suggestions, getSuggestions };
}
```

## UI Implementation: Modular Listing Cards

Keep your components focused on presentation. Use a clean, accessible layout for every property result.

```jsx
// src/components/PropertyCard.jsx
export function PropertyCard({ item }) {
  return (
    <article className="property-card">
      <img src={item.images?.[0]} alt={item.title} className="card-thumb" />
      <div className="card-body">
        <h3 className="card-title">{item.title}</h3>
        <p className="card-price">{item.price.currency} {item.price.value.toLocaleString()}</p>
        <div className="card-stats">
          <span>{item.bedrooms} Beds</span>
          <span>{item.size.value} {item.size.unit}</span>
        </div>
      </div>
    </article>
  );
}
```

## Performance Tip: Debouncing Search

To avoid hitting rate limits and to provide a smoother UX, always debounce your autocomplete requests.

```javascript
import { debounce } from "lodash";

const debouncedSearch = debounce((text) => {
  getSuggestions(text);
}, 300);
```

## Developer Benefits

- **Predictable State**: Atomic hooks ensure your filters, pagination, and results stay in sync across your application.
- **Component Reusability**: Build once and reuse your `PropertyCard` or `SearchInput` across different pages or layouts.
- **Zero Configuration**: Our standardized REST API works natively with the Fetch API, eliminating the need for bulky SDKs or client-side libraries.
- **Global Context**: Render `property.title` and `property.address.full_name` directly inside your components; both arrive as display-ready strings.

## Next Implementation Steps

1.  **SEO Optimization**: Move to the [Next.js Integration Guide](/guides/nextjs) to enable Server-Side Rendering (SSR).
2.  **Mobile Support**: Check the [Real Estate Mobile Apps Use Case](/use-cases/real-estate-mobile-apps) for building React Native applications.
3.  **Visualization**: Link your React frontend to a Python backend for complex [Market Intelligence Dashboards](/use-cases/market-research-dashboards).
