algolia / react-instantsearch

⚑️ Lightning-fast search for React and React Native applications, by Algolia.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/react/
MIT License
1.97k stars 386 forks source link

Applied refinementList item getting corrupted? when using "and" operator and running useCurrentRefinements #3640

Closed tremby closed 1 year ago

tremby commented 2 years ago

πŸ› Bug description

I am seeing an applied option from an "and"-operator refinement list appearing to become cleared when another component is added to the page which runs useCurrentRefinements.

The necessary set of conditions to see the bug seems to include a separate call to useRefinementList.

πŸ” Bug reproduction

Steps to reproduce the behavior:

  1. Go to live reproduction link below
  2. Select any of the refinements, such as "Appliances"
  3. See the applied refinement below, and notice it is "type": "facet"
  4. Click the button "Add a component which runs useCurrentRefinements"
  5. See that the checkbox has become cleared -- it should not have been!
  6. See the applied refinement, notice it is now "type": "disjunctive"

Live reproduction:

https://codesandbox.io/s/naughty-fire-kur2ey?file=/App.tsx

πŸ’­ Expected behavior

Adding a component to the page which runs that hook should not change the currently-applied refinements.

In my real use case, it is a list of currently-applied refinements, and it should only appear in certain circumstances.

Environment

Additional context

You'll notice the bug seems to disappear if removing various parts of the UI (and their hooks) I've included in the sandbox. But all of those pieces serve functions in my real use case.

tremby commented 1 year ago

This bug is still giving me grief. I wonder if someone could please take a look at it?

Haroenv commented 1 year ago

Upon some investigation (sorry that nobody saw this earlier), this happens because there's two instances of the same refinement list with different options:

  1. useRefinementList with only category
  2. RefinementList with category and operator

When a new widget mounts (via hook or being rendered) it will apply its "refinement". So the order was something like this

To solve the issue, make sure to pass the exact same options when you render the same widget multiple times. That's visible in this solved sandbox: https://codesandbox.io/s/romantic-wescoff-3xfyvw?file=/App.tsx.

tremby commented 1 year ago

Oh! Thank you very much. That makes sense.

Do I have to ensure every option is identical for both calls to useRefinementList? Or is the operator one the only one that strictly matters (along with attribute of course)?

For the attribute which was giving issues, I'm also using searchable, searchablePlaceholder, sortBy, showMore, limit, transformItems.

In case you want more context for why I'm calling the hook a second time: In my use case the second call to useRefinementList is to get information on whether any options are available in that list, since I want to style the UI based on that. It isn't convenient to have that particular logic in my RefinementList component.

I suppose I could pull out all the useRefinementList calls to the parent component and pass them through as props, though this would make things rather messier.

After passing through operator to the other call in this case I'm not seeing the problem any more. It'd be useful to know if I'm doing something dangerous though!

Haroenv commented 1 year ago

It's probably best when you want to ensure there's no conflicts that you are using all the same options, but only limit, showMoreLimit, operator would have an effect on the search parameters for refinement list