algolia / algolia/instantsearch

Cache for useInfiniteHits is not working correctly in certain situations

Open
#5,239 6 comments 13 reactions 0 assignees View on GitHub
Library: React InstantSearch ≥ 7
Dominant language
TypeScript
Stars
4.1k
Forks
553
Avg merge
1d 11h
Merged PRs (30d)
51

Description

## 🐛 Bug description

`useInfiniteHits` cache functionality breaks when hooks are used in a certain way for custom search UI components. With components from instantsearch library everything works fine.

Cache `read` callback is called multiple times and initially state doesn't include all the facets when coming back to search page and it doesn't match with what is in cache before `write` is called and cache resets.

```javascript
return cache && isEqual(cache.state, getStateWithoutPage(state)) ? cache.hits : null;
```

https://github.com/algolia/instantsearch.js/blob/master/packages/instantsearch.js/src/lib/infiniteHitsCache/sessionStorage.ts#L29

Example includes custom cache where it is easy to see that `read` function is called multiple times and state is not up to date until later and `write` gets called before state gets matched from session storage:

```javascript
const customCache = {
write: ({ hits, state }) => {
console.log("WRITE");
sessionStorage.setItem(
KEY,
JSON.stringify({
state: getStateWithoutPage(state),
hits: hits
})
);
},
read: ({ state }) => {
console.log(state);
var cache = JSON.parse(sessionStorage.getItem(KEY));
return cache && dequal(state, getStateWithoutPage(state))
? cache.hits
: null;
}
};
```

Console logs when coming back from product page

Screenshot 2022-09-12 at 12 45 12

In the logs you can see that disjunctiveFacets is empty array at first and it won't match with the one in cache. `write`gets called and cache basically resets.

`` can be uncommented to check working functionality

```javascript



{/* */}


{/* Cache resets when custom components with hooks is used */}

{/* Cache works correctly with ready made UI components */}
{/* */}

```

## 🔍 Bug reproduction

**Steps to reproduce the behavior:**

1. Go to https://codesandbox.io/s/musing-cori-g9895q
2. Click "Show more"
3. Click product to go to product page
4. Go back to search page
5. Results should have 40 items but has only 20.

**Live reproduction:**

https://codesandbox.io/s/musing-cori-g9895q

## 💭 Expected behavior

When more products have been fetched with "Show more" button and user navigates to a product page and back, search results should still have all the previously fetched products visible.

## Environment

- React InstantSearch Hooks version: 6.32.1
- React version: 18.2.0
- Browser: Chrome 104.0.5112.79
- OS: macOS

Contributor guide

Open the contributing guide

Research direction

Start at packages/instantsearch.js/src/lib/infiniteHitsCache/sessionStorage.ts around the cache read logic, then reproduce the flow in the linked CodeSandbox with custom hook-based components. Trace the state passed to read and write when returning to the search page. Done means previously fetched results, such as 40 items after “Show more,” remain visible instead of being reset to 20.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, search
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.