Skip to main content

Search

The useSearch hook provides full-text product search against the Shopify Storefront API. Unlike other listing hooks, useSearch does not fetch on mount. Instead, it exposes a search function you call in response to user input.

Usage

import { useState, useCallback } from 'react';
import { useSearch } from 'react-native-stackfront-sdk';
import { FlashList } from '@shopify/flash-list';

function SearchScreen() {
  const [query, setQuery] = useState('');
  const { data, loading, search } = useSearch();

  const handleSubmit = useCallback(() => {
    if (query.trim()) {
      search(query.trim(), 20);
    }
  }, [query, search]);

  const results = data?.edges ?? [];

  return (
    <View>
      <SearchBar value={query} onChangeText={setQuery} onSubmit={handleSubmit} />
      <FlashList
        data={results}
        renderItem={({ item }) => <ProductCard product={item.node} />}
        estimatedItemSize={300}
      />
    </View>
  );
}

Hook API

function useSearch(): {
  data: unknown;                   // search connection shape
  loading: boolean;
  error: Error | null;
  search: (query: string, first?: number) => Promise<void>;
}

Debouncing

For real-time search as the user types, debounce the input before calling search:
import { useDebounce } from '../hooks/useDebounce';

function SearchScreen() {
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query, 300);
  const { search } = useSearch();

  useEffect(() => {
    if (debouncedQuery.trim()) {
      search(debouncedQuery.trim(), 10);
    }
  }, [debouncedQuery]);

  // ...
}

Query Scope

The SEARCH_PRODUCTS GraphQL operation searches across product title, description, tags, productType, and vendor fields. Results are returned as a standard GraphQL connection with the same shape as useProducts — each edge contains the full product node with id, title, handle, description, priceRange, images(first: 1), and variants(first: 1).