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

# Use Autocomplete with React

> Learn how to create and use a React Autocomplete component.

<Tip>
  Autocomplete is also available as an experimental widget in InstantSearch,
  making it easier to integrate into your search experience.
  For more information,
  see the API reference for [InstantSearch.js](/doc/api-reference/widgets/autocomplete/js) or
  [React InstantSearch](/doc/api-reference/widgets/autocomplete/react).
</Tip>

This guide uses the [`useRef`](https://react.dev/reference/react/useRef) and
[`useEffect`](https://react.dev/reference/react/useEffect) Hooks to create and mount the component.
It doesn't define specific [sources](/doc/ui-libraries/autocomplete/core-concepts/sources).
Rather, you can pass [sources](/doc/ui-libraries/autocomplete/core-concepts/sources) and other
[options](/doc/ui-libraries/autocomplete/core-concepts/basic-configuration-options) as
[props](https://react.dev/learn/passing-props-to-a-component).

## Before you begin

The guide assumes you're familiar with the [basic Autocomplete configuration options](/doc/ui-libraries/autocomplete/core-concepts/basic-configuration-options)
and have an existing [React (v16.8+) app](https://reactjs.org/docs/getting-started.html) to which you want to add an Autocomplete menu.

## Create the component

Add the following starter code for creating a React component.
This component uses the [`useRef`](https://react.dev/reference/react/useRef) Hook to create a mutable ref object,
`containerRef`, for mounting the autocomplete.

All that you need to render is a `div` with the `containerRef` as the `ref`.

```jsx JSX icon=code theme={"system"}
import React, { Fragment, useEffect, useRef } from "react";

export function Autocomplete(props) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current) {
      return undefined;
    }
  }, [props]);

  return <div ref={containerRef} />;
}
```

### Attach the autocomplete menu to the DOM

Now that you have access to the DOM through the `containerRef` object,
you can create and mount the Autocomplete instance.
Upon instantiation, you can include any desired [Autocomplete options](/doc/ui-libraries/autocomplete/core-concepts/basic-configuration-options)
and rely on `props` to pass any options you want to remain configurable.

The following examples specify where to mount your Autocomplete component with the [`container`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-container) option,
but lets all other [options](/doc/ui-libraries/autocomplete/core-concepts/basic-configuration-options)
get configured through props.

The default Autocomplete implementation uses [Preact](https://preactjs.com/) APIs to create and render elements,
so you need to replace them with React APIs to properly render the views.
**Depending on your React version, the implementation slightly differs**.
In both cases, clean up the effect by returning a function that destroys the Autocomplete instance.

#### With React 18

With [React 18](https://react.dev/blog/2022/03/29/react-v18),
you should only pass React `createElement` and `Fragment` to the [`renderer`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-renderer) option.
To silence the warning from Autocomplete, you can pass an empty function to `renderer.render`.

Instead, you should use the [`render`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-render)
option to create a `Root` object with the React `createRoot` function, then use this object to render.

```jsx JSX icon=code theme={"system"}
import { autocomplete } from "@algolia/autocomplete-js";
import React, { createElement, Fragment, useEffect, useRef } from "react";
import { createRoot } from "react-dom/client";

export function Autocomplete(props) {
  const containerRef = useRef(null);
  const panelRootRef = useRef(null);
  const rootRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current) {
      return undefined;
    }

    const search = autocomplete({
      container: containerRef.current,
      renderer: { createElement, Fragment, render: () => {} },
      render({ children }, root) {
        if (!panelRootRef.current || rootRef.current !== root) {
          rootRef.current = root;

          panelRootRef.current?.unmount();
          panelRootRef.current = createRoot(root);
        }

        panelRootRef.current.render(children);
      },
      ...props,
    });

    return () => {
      search.destroy();
    };
  }, [props]);

  return <div ref={containerRef} />;
}
```

#### With React 16.8 or 17

With React 16.8 or 17, you need to import `createElement`, `Fragment`, and `render` from React and provide them to the Autocomplete [`renderer`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-renderer) option.

```jsx JSX icon=code theme={"system"}
import { autocomplete } from "@algolia/autocomplete-js";
import React, { createElement, Fragment, useEffect, useRef } from "react";
import { render } from "react-dom";

export function Autocomplete(props) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (!containerRef.current) {
      return undefined;
    }

    const search = autocomplete({
      container: containerRef.current,
      renderer: { createElement, Fragment, render },
      ...props,
    });

    return () => {
      search.destroy();
    };
  }, [props]);

  return <div ref={containerRef} />;
}
```

## Use the component

Now that you've created an `<Autocomplete />` component, you can use it in your React application.

The usage below sets [`openOnFocus`](/doc/ui-libraries/autocomplete/api-reference/autocomplete-js/autocomplete#param-open-on-focus) and [sources](/doc/ui-libraries/autocomplete/core-concepts/sources) through props.
This example uses an [Algolia index](https://support.algolia.com/hc/en-us/articles/4406981910289-What-is-an-index-) as a [source](/doc/ui-libraries/autocomplete/core-concepts/sources), but you could use anything else you want, including [plugins](/doc/ui-libraries/autocomplete/core-concepts/plugins).
For more information about using Algolia as a source, see [Getting started](/doc/ui-libraries/autocomplete/introduction/getting-started).

```jsx JSX icon=code theme={"system"}
import React, { createElement } from "react";
import { getAlgoliaResults } from "@algolia/autocomplete-js";
import algoliasearch from "algoliasearch";
import { Autocomplete } from "./components/Autocomplete";
import { ProductItem } from "./components/ProductItem";

const appId = "latency";
const apiKey = "6be0576ff61c053d5f9a3225e2a90f76";
const searchClient = algoliasearch(appId, apiKey);

function App() {
  return (
    <div className="app-container">
      <h1>React Application</h1>
      <Autocomplete
        openOnFocus={true}
        getSources={({ query }) => [
          {
            sourceId: "products",
            getItems() {
              return getAlgoliaResults({
                searchClient,
                queries: [
                  {
                    indexName: "instant_search",
                    query,
                  },
                ],
              });
            },
            templates: {
              item({ item, components }) {
                return <ProductItem hit={item} components={components} />;
              },
            },
          },
        ]}
      />
    </div>
  );
}

export default App;
```

### Create templates

The example preceding passes `<ProductItem />`, another React component,
for the [`item` template](/doc/ui-libraries/autocomplete/core-concepts/templates#param-templates-item).

```jsx JSX icon=code theme={"system"}
import React, { createElement } from "react";

export function ProductItem({ hit, components }) {
  return (
    <a href={hit.url} className="aa-ItemLink">
      <div className="aa-ItemContent">
        <div className="aa-ItemTitle">
          <components.Highlight hit={hit} attribute="name" />
        </div>
      </div>
    </a>
  );
}
```

## Further UI customization

If you want to build a custom UI that differs from the `autocomplete-js` output,
check out the [guide on creating a custom renderer](/doc/ui-libraries/autocomplete/guides/creating-a-renderer).
This guide outlines how to create a custom React renderer specifically,
but the underlying principles are the same for any other frontend framework.
