How to know when to identify first render in InfiniteHits (ReactInstantSearch flavour)

I’ve implemented by my own InfiniteHits components using connectInfiniteHits connector:

const InfiniteHits =
    ({
         hits,
         hasPrevious,
         refinePrevious,
         hasMore,
         refineNext,
     }) => { ... }

Now I need to render Skeleton/Ghost elements before the first results arrive. In the InstantSearch flavour there’s a function called isFirstRender that could be used for that purpose, but it’s not available in ReactInstantSearch flavour. What’s the recommended approach for React flavour (function based) to identify the point before first results arrive?

If I understand well, you’d like to render more content than the hits. In this case, we recommend using connectInfinitHits which allows you to render your own components.

Hey, I’m already using my custom version of InfiniteHits through connectInfiniteHits as I’ve specified in my post:

The problem is that I have to know when the initial search query started and finished. I need to know that because I want to show a skeleton layout onсe before the results for the initial query are available.

Right, then it seems like you want to use connectStateResults to know if the search is in progress.

Thanks, so how do I detect the initial search using it? Should I use searching attribute to detect when the first search started and finished and show skeleton layout during this search, but then switch to regular loading indicator for the subsequent searches?

Hi there,

initial” really depends on how you define it in your app.

Here is an example for you. You can literally take the first search as “initial search” like I did in App.js@22.

1 Like

@eunjae.lee, thanks for the example! connectStateResults is what I needed. I also put <Hits> inside state results to show either skeleton or results. In your example you’re using searchResults to find out if the first search has taken place:

const CustomStateResults = connectStateResults(
  ({ searchResults, searching }) => {
    const [isInitialSearch, setInitialSearch] = useState(true);

    if (searchResults && isInitialSearch) {
      setInitialSearch(false);
    }

I’m wondering though if it’s the correct logic. As I understand, StateResults is initialized with an empty array forsearchResults even if the search hasn’t been initiated yet. If so, how would you distinguish between first render and empty dataset returned from the server?

I’m using searchIndex and trying to capture first active search during which the skeleton is shown:

let searchIndex = 0;
let isFirstSearchActive = false;

const StateResults =
    ({
         searchState,
         searchResults,
         allSearchResults,
         error,
         searching,
         searchingForFacetValues,
         isSearchStalled,
         children,
     }) => {
        if (searchIndex === 0 && searching === true) {
            isFirstSearchActive = true;
            searchIndex += 1;
        } else {
            isFirstSearchActive = false;
        }

        return !isFirstSearchActive
            ? children
            : (<div style={{ fontSize: "100px" }}>SHOWING SKELETON SITE</div>);
    };

There’s indeed no built-in way to detect if it’s coming from a first search (no results yet) or from another search (no results).

We’ll try to address this case (which is essential IMO) when reworking the lifecycle. Thanks!

1 Like

great, thanks! looking forward to having a proper solution