Exporting react-instantsearch state

Hey, so I’m using a service worker to cache all of my requests so that everything on the site works when you are offline. I’m also storing my state for random requests using redux. This means that if a user goes offline, they can click anywhere on the site and still see anything that was loaded in the past. The one problem is with the algolia search piece. If there was a way to hook into the InstantSearch component and store the state myself, this problem would be solved. Any ideas on how to do this? Thanks!

Hi there,

You can manage the state yourself by passing a searchState object prop (which you can fetch from your Redux state) and by passing a onSearchStateChange prop which states how the state updates should be handled; using Redux, you would probably want to dispatch any state change in the following way:

<InstantSearch
 searchState={myReduxState}
 onSearchStateChange={(state) => this.props.dispatch({ type: 'STATE_CHANGE', state })}
>
  ...
</InstantSearch>

You can find a more complete explanation here:

Let me know if this is helps you out!

This isn’t what I’m talking about. I’m talking about storing the entire state as in, all the hits, facets, etc that are loaded.

Hi there,

Sorry for the misunderstanding: indeed that’s not what you need.

As far as I know there’s no direct way to inject a whole state since react-instantsearch uses a lots of components in the background which either maintains their own state or they don’t expose it.

Probably your best bet would be to use a custom connector + redux-connect to inject the part of the widget you want to populate:

import {connect} from 'react-redux';
import {createConnector} from 'react-instantsearch';

function Hits({hits}) {
  ...
}

function mapStateToProps(state) {
  return {
    storedHits: state.hits
  };
}

const withReduxState = connect(mapStateToProps)(
  createConnector({
    displayName: 'HitsFromReduxState',
    getProvidedProps(props, searchState, searchResults) {

      if (!searchResults.results || !props.storedHits) {
        return null;
      }

      return {
        hits: props.storedHits || searchResults.results.hits
      }
    },
    getSearchParameters(searchParameters) {
      return searchParameters;
    }
  })
);

export default ConnectedHits = withReduxState(Hits);

The problem with this approach is that you will need to write a lor connectors to support this kind of logic (one for each widget you want to populate with redux state).

Another interesting approach would be to cache Algolia requests on your Service Worker but unfortunately POST request are not cacheable so you’ll need to come up with your own caching solution (IndexedDB for example).

Let me know if you found a working approach to your problem, I’m definitely interested to hear more about it :slight_smile:

Too bad the requests aren’t via get :slight_smile: Thanks for the help. I’ll post back when I decide on something.

@development By default all requests are kept in memory by the JavaScript client used internally by react-instantsearch.

So if you type “coca” and get results, then you disconnect from the internet, you will be able to show:

  • empty query results (first page shown)
  • c, co, coc, coca results (every letter leading to a request)

If you would like to keep the requests results not just in memory but somewhere else and have react-instantsearch use that cache this is also doable. Let me know how it goes.