React-instantsearch: `connectStateResults` does not provide up-to-date values in server side rendering

Created on 1 Mar 2021  路  12Comments  路  Source: algolia/react-instantsearch

Describe the bug 馃悰

In some cases, connectStateResults does not provide the correct up-to-date values.

To Reproduce 馃攳

Unfortunately, it's not possible for me to give a working example here. But the flow is as follow:

  • The user lands on the search page.
  • They see a list of results L1.
  • They update and submit a new query.
  • They do see the list of results L2. In the network tab, the request fired to Algolia API works successfully. But because connectStateResults is not correctly updated, searching remains true - and, in our implementation, the spinner keeps spinning, on top of several other unwanted side-effects. The provided searchResults is also not correctly updated.

Expected behavior 馃挱

connectStateResults should always provide the latest values. There should not be a difference between the provided searchResults.hits and the hits provided by connectHits, for instance. Nor there should be a difference between the provided searchState.query and searchResults.query.

Environment:

  • OS: MacOS
  • Browser: Chrome
  • Version: 88

Additional context

We're using the latest 6.10.0 version of both react-instantsearch-core and react-instantsearch-dom.

We're using the following connectors:

  • connectSearchBox. When submitting the search query, I'm calling the provided refine method with the query.
  • connectHits. The hits are always up to date, there is absolutely no issue there.
  • connectStateResults. Somehow, when using the React inspector, we can see that:

    • searchState is up to date. It contains the latest query.

    • searching sometimes remains true until a new search query is fired.

    • searchResults sometimes contain the previous results until a new search query is fired. This also means that searchResults.query contains the previous query, as opposed to searchState.query, where the up-to-date query can be found.

We're also using server-side rendering, click analytics, and conversion analytics. Here is how the configure component looks like:

        <Configure
            optionalFilters={optionalFilters}
            filters={filters}
            queryLanguages={queryLanguages}
            hitsPerPage={hitsPerPage}
            removeWordsIfNoResults="lastWords"
            clickAnalytics
            analytics
        />

The search is performed on a single index, correctly passed to InstantSearch.

All 12 comments

Unsure if this will help, but it feels like these two issues are kind of related?

Hey @ksntcrq, do you have a sandbox with this behaviour? Is it not happening when you use 6.9.0? Thanks!

looks like it's a duplicate of #3018 indeed. Feel free to give more information on your problem there, and use 6.9.0 in the mean time

@Haroenv It does happen on 6.9.0, as well as 6.8.2. Could you please reopen?

I misunderstood the issue then, sorry!

https://github.com/algolia/react-instantsearch/pull/2953 sounds similar to the issue you're having

I've been trying to reproduce this the last couple of days, but always come short of touching the actual problem. Eg. I made https://codesandbox.io/s/charming-nash-cq896?file=/src/App.js, but there I always see searchResults being updated and a render using searching: false.

To debug this properly, I'd love to see a sandbox that shows this behaviour

I'm not sure what causes the bug yet, but in the mean time, you could use connectHits and connectSearchBox instead of connectStateResults in your use case if you see the data not being correct.

I sent a working version in private to @mathougui, let me know if you need more details.

The component using searching also uses query and nbHits from searchResults, so I'm afraid I can't only use connectHits and connectSearchBox, but I'll try to find a workaround with this idea in mind. Thanks!

The issue seems to be introduced as soon as we're using connectHitInsights. Because we have server-side rendering, we do it this way:

export default connectHitInsights(getAlgoliaAnalytics())(CustomHit);
export function getAlgoliaAnalytics() {
    if (isServerSide()) {
        return null;
    }

    if (isEmpty(window.aa)) {
        return null;
    }

    return window.aa;
}

I managed to reproduce here. Just type two letters in the input, and see the outdated log in the console.

I simplified the example and found the following things that matter: https://codesandbox.io/s/stoic-hermann-98bx9?file=/pages/index.js

  1. stateResults behind hits has the issue, before it doesn't
  2. a hitComponent must be given in default Hits component

For your specific use case, can you try putting StateResults in front of Hits?

Changing the order seems to be working. Thanks!

Found some more things: https://codesandbox.io/s/billowing-browser-gd3kn?file=/src/App.js

  • resultsState is required for this to misbehave
  • it doesn't have to be server-side rendered
  • only the first StateResults has outdated results
  • if key is index (not objectID), the issue doesn't happen
Was this page helpful?
0 / 5 - 0 ratings