React-instantsearch: The connectStateResults hoc injected props allSearchResults behaviour is different between v5.7.0 and v6.0.0

Created on 27 Nov 2019  路  9Comments  路  Source: algolia/react-instantsearch

Context

We have a component will render no results placeholder when all the all of the indexes have no results.

We achieve the feature by using connectStateResults HOC. After upgrade to v6 from v5.7, we can't access index search results.

Describe the bug 馃悰

The connectStateResults hoc injected props allSearchResults behavior is different between v5.7.0 and v6.0.0

In v5, the allSearchResults a new object reference will assigned when ever a new index be fetched.

In v6, the allSearchResults object will updated by mutated

To Reproduce 馃攳

checking out the repo that I prepare for this issue. Switch between branches to test out behavior.

A live example helps a lot! We have a simple online template for you to use for your explanations:

https://github.com/hongchanhk01/test-react-instantsearch

  • master branch (v6.0.0)
  • react-instantsearch-v5 (v5.7.0)

Screenshot
v5
image

v6
image

PS: if you encounter file not found problem by the bundler when switching branch. Trying remove the .cache and start the server again

Expected behavior 馃挱

The allSearchResults props should not have been mutated. Instead it should given a new Object reference every time an index fetched.

Environment:

  • OS: MacOS
  • Browser Chrome
  • Version 78

This happen in all browsers as well

鉂わ笍 Bug

All 9 comments

So far I indeed have been able to confirm this in your environment, but have not yet found what causes it. Thanks for the bug report and reproduction!

@Haroenv

I have a dirty quick fix on this. what do think ?

https://github.com/algolia/react-instantsearch/blob/master/packages/react-instantsearch-core/src/connectors/connectStateResults.js#L65

    return {
      searchState,
      searchResults: results,
      allSearchResults: Object.assign({}, searchResults.results), // Quick fixes here
      searching: searchResults.searching,
      isSearchStalled: searchResults.isSearchStalled,
      error: searchResults.error,
      searchingForFacetValues: searchResults.searchingForFacetValues,
      props,
    };

but still I think it is better to find out why. My guess is that results inside the contextValue store reference not updated.

https://github.com/algolia/react-instantsearch/blob/master/packages/react-instantsearch-core/src/core/createConnector.tsx#L218

Yes, I also found the dirty fix, but not yet sure what causes it. I wonder if it's caused by stale closures

I also ran into this problem. We were also making a component to render a "No results" when multiple indexes all don't have results. It was pretty nasty figuring out why I could go into dev tools and see the value of allSearchResults but not see it reflected in the UI.

The dirty fix I used was I had another component sit in the middle.

const ComponentWithAllResults = ({allSearchResults, ...rest }) => (
   <Component allSearchResults={ deepCopy(allSearchResults) } {...rest} />
)

AllResults = connectStateResults(ComponentWithAllResults)

I am running into the same issue. I opened a topic in discourse.

The codesandbox running react-instantsearch v6.4.0 showing how to reproduce this issue can be found here

The same codesandbox running react-instantsearch v5.7.0 does not have this issue, and can be viewed here

Hi, is there any news about this issue? This is also happening on v6.6.0. Thanks!

I had this issue too on 6.7.0. My fix was pretty simple: Always pass the children down the tree regardless of if there are results. Since the results are empty anyway (at least for me), passing the children gave no weird results:

const AllResults = connectStateResults(({ searchState, allSearchResults, children }) => {
  const hasResults =
    searchState?.query &&
    allSearchResults &&
    Object.values(allSearchResults).some((results) => results.nbHits > 0)
  // children has to be passed in order for allSearchResults to be updated:
  return hasResults === false ? (
    <>
      <div>No Results Found</div>
      {children}
    </>
  ) : (
    children
  )
})

I had this issue too on 6.7.0. My fix was pretty simple: Always pass the children down the tree regardless of if there are results. Since the results are empty anyway (at least for me), passing the children gave no weird results:

const AllResults = connectStateResults(({ searchState, allSearchResults, children }) => {
  const hasResults =
    searchState?.query &&
    allSearchResults &&
    Object.values(allSearchResults).some((results) => results.nbHits > 0)
  // children has to be passed in order for allSearchResults to be updated:
  return hasResults === false ? (
    <>
      <div>No Results Found</div>
      {children}
    </>
  ) : (
    children
  )
})

@ericconstantinides
I am not quite sure what you mean. but I just double checked by using the codesandbox example https://github.com/algolia/react-instantsearch/issues/2875#issuecomment-605981989 and upgrade to 6.7.0. Seem the issue fixed for me.

May I know more details about your issue ?

@ericconstantinides
I am not quite sure what you mean. but I just double checked by using the codesandbox example #2875 (comment) and upgrade to 6.7.0. Seem the issue fixed for me.

May I know more details about your issue ?

My fix was in reference to showing No Results with multi-indices. Here's a link to what it fixes in the Algolia Docs.

Was this page helpful?
0 / 5 - 0 ratings