algolia / instantsearch

⚡️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/
MIT License
3.68k stars 515 forks source link

[react-instantsearch-hooks] hits/hits.results from useInfiniteHits #5242

Open RobbyUitbeijerse opened 2 years ago

RobbyUitbeijerse commented 2 years ago

Howdy!

We are using useInfiniteHits to return us a nice list with results for our overview page that has a 'load more items' option. We are doing this all client side, and aren't working with the SSR provider just yet

We started meddling with routing and controlling the UI state through the initialUiState prop on the InstantSearch component. Now let's say the state we provide in the initialUiState is as follows

      initialUiState={{
        products: {
          configure: {
            hitsPerPage: 10,
          },
          menu: {
            currency: 'euro',
          },
        },
      }}

The state throughout the application that is retrieved through the hooks is reflecting this initial UI state nicely - so far all good except for this one:

  const { hits, results, showMore } = useInfiniteHits(props);

The first set of hits (the first 10, based on the configuration provided in initialUiState) seem to be any hit, so: hits that are not filtered based on the initialUiState, but simply the first 10 of the products index it's default ordering.

Now this is where it gets a bit funky:

In the results prop, the correct 10 items are actually provided - so Algolia did actually run the query and does have the correct hits. Of course, the results.hits are only the items of the current page, so we can't use this prop with our showMore set-up.

Once we initiate the showMore, and thus load the next 10 results (to get a total of 20 hits): the hits prop is still showing the first 10 items to be any hit. The next 10 (page 2), are the items we would expect to show up on page 2.

Once we turn on a random facet or sorting option, and turn it back again to a state that matches the initialUiState as provided, everything is correct. It seems to 'trigger' something that makes the output of useInifniteHits go to the correct state (just one extra rerender that fixes it?)

tl;dr: It seems to be that the first set of hits in the hits property of useInifniteHits doesn't reflect a filtered items, based on the initialUiState provided. results.hits actually has the correct items, but since we are implementing a 'click here to show more' scenario, we can't use this.

Let me know if this makes sense, if it doesn't I'm happy to try to replicate the situation

francoischalifour commented 2 years ago

This seems to be a caching issue. Are you using the cache prop?

If not, it'd be helpful to get a reproduction in this sandbox.

RobbyUitbeijerse commented 2 years ago

Hey! unfortunately no, but I can see how that could have been the issue. Will create a sandbox/example tomorrow!

Haroenv commented 2 years ago

While this definitely sounds like a bug we will look into and find the root cause, I'd just like to mention that React InstantSearch hooks has a routing option that doesn't require initialUiState too. You can find the documentation for that here: https://www.algolia.com/doc/api-reference/widgets/instantsearch/react-hooks/#widget-param-routing and https://www.algolia.com/doc/guides/building-search-ui/going-further/routing-urls/js/

RobbyUitbeijerse commented 2 years ago

Interestingly multiple issues I was facing (including the one reported) kind of 'vanished' once I moved our application from using multiple instances of the useInifniteHits() (note: all instances were without any options/props) hook to just one singular instance of that function high up in the component tree, and then passing on the hits and results instead of getting them from the hook everywhere.

I'm still aiming to create that repro, but I might not get to it today and wanted to let you know about this finding as it seems rather specific / interesting. Not sure what could cause the mismatch in data throughout the tree in some of the instances 🤔

[Edit] it also means it's actually unrelated to my initial suspect the (managing state manually), something else seems to be going on

Haroenv commented 2 years ago

What could be interesting to see if it could be related to the nesting or multiple times calling the same hook from the same component or its children. Do you see any minimal reproduction or does this only reproduce in a more "complex" app for now?

mikey0000 commented 7 months ago

This seems similar to an issue I'm facing when programmatically calling showMore, I'm using cache as well, goal is I want to highlight a specific result by object ID so if its not on the first page I want the next and so on, but when I do this the cache doesn't update correctly.