Using Autocomplete with React
This guide shows how to create a React Autocomplete component. It uses the useRef
and useEffect
hooks to create and mount the component. It doesn’t define specific sources. Rather, you can pass sources and other options as props.
Prerequisites
This tutorial assumes that you have:
- an existing React (v16.8+) application where you want to implement the autocomplete menu
- familiarity with the basic Autocomplete configuration options
Creating the component
Start with some boilerplate for creating a React component. This component uses the useRef
hook to create a mutable ref object, containerRef
, to mount the autocomplete on. To learn more about this hook, check out the useRef
React documentation.
All that you need to render is a div
with the containerRef
as the ref
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}
}, [props]);
return <div ref={containerRef} />;
}
Mounting the autocomplete
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 and rely on props
to pass any options you want to remain configurable.
The example component below sets only the container
option. It specifies where to mount your Autocomplete component, but lets all other options get configured through props.
You must also pass the renderer
and render
parameters. This is because the default Autocomplete implementation uses Preact’s version of createElement
, Fragment
and render
. Without providing React’s version of these, the Autocomplete instance won’t render the views properly.
Don’t forget to clean up the effect by returning a function that destroys the Autocomplete instance.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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({ children }, root) {
render(children, root);
},
...props,
});
return () => {
search.destroy();
};
}, [props]);
return <div ref={containerRef} />;
}
Using the component
Now that you’ve created an <Autocomplete />
component, you can use it in your React application.
The usage below sets openOnFocus
and sources through props. This example uses an Algolia index as a source, but you could use anything else you want, including plugins. For more information on using Algolia as a source, check out the Getting Started guide.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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;
Creating templates
The example preceding passes <ProductItem />
, another React component, for the item
template.
1
2
3
4
5
6
7
8
9
10
11
12
13
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. This guide outlines how to create a custom React renderer specifically, but the underlying principles are the same for any other front-end framework.