UI libraries / React InstantSearch / Widgets

This is the React InstantSearch v7 documentation. React InstantSearch v7 is the latest version of React InstantSearch and the stable version of React InstantSearch Hooks.

If you were using React InstantSearch v6, you can upgrade to v7.

If you were using React InstantSearch Hooks, you can still use the React InstantSearch v7 documentation, but you should check the upgrade guide for necessary changes.

If you want to keep using React InstantSearch v6, you can find the archived documentation.

Signature
const { renderState } = useInstantSearch();

About this widget

The renderState property provides all the data and functions from the widgets. It lets you access the render state of any widget, so you can create custom widgets or refine the search outside the InstantSearch lifecycle.

This is mainly useful for creating components that interact with multiple widgets at once, without mounting as many widgets.

A good example would be showing which filters of a hit are applied.

Examples

You can access the render state of the searchBox widget.

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
const indexName = '<index-name>';

function App({ searchClient }) {
  return (
    <InstantSearch indexName={indexName} searchClient={searchClient}>
      <SearchBox />
      <RenderState />
    </InstantSearch>
  );
}

function RenderState() {
  const { renderState, indexRenderState } = useInstantSearch();

  console.log(renderState[indexName].searchBox);
  console.log(indexRenderState.searchBox);
  /*
  {
    query: string;
    refine: Function;
    clear: Function;
    isSearchStalled: boolean;
    widgetParams: object;
  }
*/

  return null;
}

Working with virtual widgets

To access the renderState of widgets, you must add them to InstantSearch. If you don’t want to add a widget to the UI, but want to get access to its renderState, you can add it as a virtual, or renderless widget.

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
function VirtualPagination(props) {
  usePagination(props);
  return null;
}

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

  return (
    <button
      onClick={() =>
        indexRenderState.pagination?.refine(
          indexRenderState.pagination?.currentRefinement + 1
        )
      }
    >
      Next Page
    </button>
  );
}

function App({ searchClient }) {
  return (
    <InstantSearch indexName="indexName" searchClient={searchClient}>
      <VirtualPagination />
      <NextPage />
    </InstantSearch>
  );
}

Example: interactive categories in a hit

In this example, we want to display a list of categories in a hit, and let users refine the search by clicking on them.

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
function App({ searchClient }) {
  return (
    <InstantSearch indexName="indexName" searchClient={searchClient}>
      <SearchBox />
      <RefinementList attribute="categories" />
      <Hits hitComponent={HitComponent} />
    </InstantSearch>
  );
}

function HitComponent({ hit }) {
  const { indexRenderState } = useInstantSearch();
  const refine = indexRenderState.refinementList?.categories?.refine;

  return (
    <div>
      <Highlight hit={hit} attribute="name" />
      <ul>
        {hit.categories.map((category) => (
          <li key={category}>
            <button
              onClick={() => {
                refine(category);
              }}
            >
              {category}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Type definition

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
type RenderState = {
  [indexId: string]: IndexRenderState;
}

type IndexRenderState = Partial<{
  searchBox: SearchBoxState;
  autocomplete: AutocompleteState;
  breadcrumb: BreadcrumbState;
  clearRefinements: ClearRefinementsState;
  configure: ConfigureState;
  currentRefinements: CurrentRefinementsState;
  hierarchicalMenu: {
    [attribute: string]: HierarchicalMenuState;
  }
  hits: HitsState;
  infiniteHits: InfiniteHitsState;
  analytics: AnalyticsState;
  places: PlacesState;
  poweredBy: PoweredByState;
  range: {
    [attribute: string]: RangeState;
  ratingMenu: {
    [attribute: string]: RatingMenuState;
  };
  numericMenu: {
    [attribute: string]: NumericMenuState;
  };
  voiceSearch: VoiceSearchState;
  geoSearch: GeoSearchState;
  queryRules: QueryRulesState;
  hitsPerPage: HitsPerPageState;
  pagination: PaginationState;
  refinementList: {
    [attribute: string]: RefinementListState;
  };
  answers: AnswersState;
}>;
Did you find this page helpful?