> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# useInstantSearch

> React Hook for accessing state and results of your React InstantSearch apps.

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

<Note>
  This is the **React InstantSearch v7** documentation.
  If you're upgrading from v6, see the [upgrade guide](/doc/guides/building-search-ui/upgrade-guides/react/#migrate-from-react-instantsearch-v6-to-react-instantsearch-v7).
  If you were using React InstantSearch Hooks,
  this v7 documentation applies—just check for [necessary changes](/doc/guides/building-search-ui/upgrade-guides/react/#migrate-from-react-instantsearch-hooks-to-react-instantsearch-v7).
  To continue using v6, you can find the [archived documentation](https://algolia.com/old-docs/deprecated/instantsearch/react/v6/api-reference/instantsearch/).
</Note>

```tsx Signature theme={"system"}
  const {
    indexUiState,
    setIndexUiState,
    uiState,
    setUiState,
    indexRenderState,
    renderState,
    results,
    scopedResults
    refresh,
    status,
    error,
    addMiddlewares,
  } = useInstantSearch({
    catchError
  })
```

## Import

```jsx JavaScript icon=code theme={"system"}
import { useInstantSearch } from "react-instantsearch";
```

## About this Hook

A React Hook that lets you access the InstantSearch API and interact with its state.

This is useful to access and update the UI state, access the search results, refresh the search, or use middleware.

Hooks must be used inside the [`<InstantSearch>`](/doc/api-reference/widgets/instantsearch/react) component.

## Examples

<CodeGroup>
  ```jsx indexUiState theme={"system"}
  import {
    InstantSearch,
    RefinementList,
    useInstantSearch,
  } from "react-instantsearch";

  function Discounts() {
    const { indexUiState, setIndexUiState } = useInstantSearch();
    const disabled = indexUiState.refinementList?.discounts?.includes("-50% off");

    return (
      <button
        type="button"
        disabled={disabled}
        onClick={() => {
          setIndexUiState((prevIndexUiState) => ({
            ...prevIndexUiState,
            refinementList: {
              ...prevIndexUiState.refinementList,
              discounts: ["-50% off", "free shipping"],
            },
          }));
        }}
      >
        Show discounts
      </button>
    );
  }

  function App({ searchClient }) {
    return (
      <InstantSearch searchClient={searchClient} indexName="instant_search">
        <Discounts />
        <RefinementList attribute="discounts" />
      </InstantSearch>
    );
  }
  ```

  ```jsx uiState theme={"system"}
  import {
    InstantSearch,
    Hits,
    SearchBox,
    useInstantSearch,
  } from "react-instantsearch";

  function App({ searchClient }) {
    return (
      <InstantSearch searchClient={searchClient} indexName="instant_search">
        <SearchBox />
        <NoResultsBoundary fallback={<NoResults />}>
          <Hits />
        </NoResultsBoundary>
      </InstantSearch>
    );
  }

  function NoResultsBoundary({ children, fallback }) {
    const { results } = useInstantSearch();

    if (!results.__isArtificial && results.nbHits === 0) {
      return fallback;
    }

    return children;
  }

  function NoResults() {
    const { setUiState } = useInstantSearch();

    return (
      <div>
        <p>No results.</p>

        <button
          onClick={() => {
            setUiState({});
          }}
        >
          Reset search
        </button>
      </div>
    );
  }
  ```

  ```jsx indexRenderState theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Refine() {
    const { indexRenderState } = useInstantSearch();

    return (
      <button
        onClick={() => {
          indexRenderState.refinementList.brand.refine("apple");
        }}
      >
        Toggle "apple"
      </button>
    );
  }
  ```

  ```jsx renderState theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Refine() {
    const { renderState } = useInstantSearch();

    return (
      <button
        onClick={() => {
          renderState.instant_search.refinementList.brand.refine("apple");
        }}
      >
        Toggle "apple"
      </button>
    );
  }
  ```

  ```jsx results theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Stats() {
    const { results } = useInstantSearch();

    return (
      <div>
        {results.nbHits} results found for the query "{results.query}".
      </div>
    );
  }
  ```

  ```jsx scopedResults theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Stats() {
    const { scopedResults } = useInstantSearch();

    const totalNbHits = scopedResults.reduce(
      (acc, { results }) => acc + results.nbHits,
      0,
    );

    return <div>{totalNbHits} results found across all indices.</div>;
  }
  ```

  ```jsx refresh theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Refresh() {
    const { refresh } = useInstantSearch();

    return <button onClick={refresh}>Refresh</button>;
  }
  ```

  ```jsx middleware theme={"system"}
  import { createInsightsMiddleware } from "instantsearch.js/es/middlewares";
  import { useInstantSearch } from "react-instantsearch";

  function InsightsMiddleware(props) {
    const { addMiddlewares } = useInstantSearch();

    // The Insights middleware is added in a layout effect because it mounts
    // a <Configure> widget. Widgets must be added in layout effects to minimize
    // the number of network requests.
    useLayoutEffect(() => {
      const middleware = createInsightsMiddleware(props);

      return addMiddlewares(middleware);
    }, [addMiddlewares, props]);

    return null;
  }
  ```

  ```jsx status theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Status() {
    const { status } = useInstantSearch();

    if (status === "loading" || status === "stalled") {
      return <>Loading...</>;
    }
  }
  ```

  ```jsx error theme={"system"}
  import { useInstantSearch } from "react-instantsearch";

  function Error() {
    const { error } = useInstantSearch({ catchError: true });

    if (error) {
      return <>Search error: {error.message}</>;
    }
  }
  ```
</CodeGroup>

## Parameters

<ParamField body="catchError" type="boolean" default={false}>
  If `true`, errors thrown by InstantSearch are handled by InstantSearch
  and are available in the [`error`](#param-error) property.
  Set `catchError` to `false` if you want to handle these errors elsewhere.
</ParamField>

## Returns

<ParamField body="indexUiState" type="IndexUiState">
  The [`uiState`](/doc/api-reference/widgets/ui-state/react) of the parent <Index />.
</ParamField>

<ParamField body="setIndexUiState" type="(indexUiState: IndexUiState) => void | ((prevIndexUiState: IndexUiState) => IndexUiState) => void">
  Updates the [`uiState`](/doc/api-reference/widgets/ui-state/react) of the parent index.

  This function either takes a new index [`uiState`](/doc/api-reference/widgets/ui-state/react) object,
  or a function that exposes the current index [`uiState`](/doc/api-reference/widgets/ui-state/react) object and returns a new one.

  <Note>
    Make sure to mount the widget responsible for the UI state.
    For example, mount a [`<RefinementList>`](/doc/api-reference/widgets/refinement-list/react)
    (or a [virtual widget](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/react#build-virtual-widgets-with-hooks))
    for the `refinementList` UI state to take effect.
  </Note>

  <CodeGroup>
    ```jsx Function theme={"system"}
    setIndexUiState((prevIndexUiState) => ({
      ...prevIndexUiState,
      refinementList: {
        ...prevIndexUiState.refinementList,
        discounts: ["-50% off", "free shipping"],
      },
    }));
    ```

    ```jsx Object theme={"system"}
    setIndexUiState({
      refinementList: {
        discounts: ["-50% off", "free shipping"],
      },
    });
    ```
  </CodeGroup>
</ParamField>

<ParamField body="results" type="SearchResults">
  The search results.
</ParamField>

<ParamField body="uiState" type="UiState">
  The [`uiState`](/doc/api-reference/widgets/ui-state/react) of the search.

  This is an object with each index name as key and the current UI state for that index as value.
</ParamField>

<ParamField body="setUiState" type="(uiState: UiState) => void | ((prevUiState: UiState) => UiState) => void">
  Function to update the [`uiState`](/doc/api-reference/widgets/ui-state/react) of the search.

  This function either takes a new [`uiState`](/doc/api-reference/widgets/ui-state/react) object,
  or a function that exposes the current [`uiState`](/doc/api-reference/widgets/ui-state/react) object and returns a new one.

  <Note>
    Make sure to mount the widget responsible for the UI state.
    For example, mount a [`<RefinementList>`](/doc/api-reference/widgets/refinement-list/react)
    (or a [virtual widget](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/react#build-virtual-widgets-with-hooks))
    for the `refinementList` UI state to take effect.
  </Note>

  <CodeGroup>
    ```tsx Function theme={"system"}
    const indexName = 'instant_search';
    setIndexUiState((prevUiState) => ({
      ...prevUiState,
      [indexName]: {
        ...prevUiState[indexName].refinementList,
        refinementList: {
          ...prevUiState[indexName].refinementList,
          discounts: ['-50% off', 'free shipping'],
        },
      },
    }));
    ```

    ```jsx Object theme={"system"}
    const indexName = "instant_search";
    setIndexUiState({
      [indexName]: {
        refinementList: {
          discounts: ["-50% off", "free shipping"],
        },
      },
    });
    ```
  </CodeGroup>
</ParamField>

<ParamField body="scopedResults" type="ScopedResult[]">
  An array with the results of the index,
  as well as the results of all adjacent [`<Index>`](/doc/api-reference/widgets/index-widget/react) widgets.

  ```ts TypeScript icon=code theme={"system"}
  type ScopedResult = {
    indexId: string;
    results: SearchResults;
  };
  ```
</ParamField>

<ParamField body="indexRenderState" type="IndexRenderState">
  The [`renderState`](/doc/api-reference/widgets/render-state/react) of the parent index.
</ParamField>

<ParamField body="renderState" type="RenderState" post={['since: v7.2.0']}>
  The [`renderState`](/doc/api-reference/widgets/render-state/react) of the search.
</ParamField>

<ParamField body="refresh" type="() => void">
  Clears the search client's cache and performs a new search.

  This is useful to update the results once an indexing operation has finished.
</ParamField>

<ParamField body="addMiddlewares" type="(...middlewares: Middleware[]) => () => void">
  Adds a [`middleware`](/doc/api-reference/widgets/middleware/js). It returns its own cleanup function.

  ```jsx JavaScript icon=code theme={"system"}
  import { myMiddleware } from "./myMiddleware";

  function MyMiddleware() {
    const { addMiddlewares } = useInstantSearch();

    useEffect(() => {
      return addMiddlewares(myMiddleware);
    }, [addMiddlewares]);

    return null;
  }
  ```
</ParamField>

<ParamField body="status" type="idle | loading | stalled | error">
  The status of the search happening.

  Possible values are:

  * `'idle'`. There currently is no search happening.
  * `'loading'`. The search is loading. This can be used for immediate feedback of an action, but for loading indicators, use `'stalled'` instead.
  * `'stalled'`. The search is stalled. This gets triggered after [`stalledSearchDelay`](/doc/api-reference/widgets/instantsearch/react#param-stalled-search-delay) expires.
  * `'error'`. The search failed. The error is available in the `error` property.
</ParamField>

<ParamField body="error" type="Error | undefined">
  The error that occurred during the search. This is only valid when `status` is `'error'`.
</ParamField>
