instantsearch icon indicating copy to clipboard operation
instantsearch copied to clipboard

Remix useFetcher() cannot be used inside InstantSearch

Open lildesert opened this issue 1 year ago • 1 comments

🐛 Current behavior

Hi,

One of the numerous frustrations I got from trying to use algolia with Remix is that I cannot use useFetcher() in any component that is a child of <InstantSearch>. The InstantSearch component affects the react-router behavior (which Remix uses under the hood). On new versions of Remix, the thrown error is the following useFetcher must be used inside a RouteContext. So I guess InstantSearchContext doesn't pair well with Remix RouteContext.

Small edit: it seems related to SSR since an easy workaround is to render the component only client-side with ClientOnly for example.

Thanks for any help on this!

🔍 Steps to reproduce

Just use Remix useFetcher in any component inside <InstantSearch>. See sandbox for reproduction.

Live reproduction

https://codesandbox.io/p/sandbox/remix-algolia-usefetcher-h3x9rh

💭 Expected behavior

useFetcher() works out of the box and allows me to fetch or post data.

Package version

react-instantsearch 7.2.0, remix 2.2.0, algoliasearch 4.20.0

Operating system

No response

Browser

No response

Code of Conduct

  • [X] I agree to follow this project's Code of Conduct

lildesert avatar Nov 15 '23 15:11 lildesert

Hi @lildesert

The problem is the component is not being rendered in the Remix context it needs.

There are 2 ways to circumvent this :

  • You can check whether you are in a Remix context before rendering ComponentWithFetcher
  • You can mock a Remix context for the first SSR pass so that it doesn't throw : https://codesandbox.io/p/devbox/remix-algolia-usefetcher-forked-lppcvf?file=%2Fapp%2Froutes%2Findex.tsx%3A49%2C32

aymeric-giraudet avatar Nov 22 '23 14:11 aymeric-giraudet

Hi @lildesert

It's late but all you need is a serverState from loader, so it's perfectly legal to to duplicate an InstantSearch component in the loader that does not depend on Remix/React context, you can use composition to minimize the duplication.

🐛 Current behavior

Hi,

One of the numerous frustrations I got from trying to use algolia with Remix is that I cannot use useFetcher() in any component that is a child of <InstantSearch>. The InstantSearch component affects the react-router behavior (which Remix uses under the hood). On new versions of Remix, the thrown error is the following useFetcher must be used inside a RouteContext. So I guess InstantSearchContext doesn't pair well with Remix RouteContext.

Small edit: it seems related to SSR since an easy workaround is to render the component only client-side with ClientOnly for example.

Thanks for any help on this!

🔍 Steps to reproduce

Just use Remix useFetcher in any component inside . See sandbox for reproduction.

Live reproduction

https://codesandbox.io/p/sandbox/remix-algolia-usefetcher-h3x9rh

💭 Expected behavior

useFetcher() works out of the box and allows me to fetch or post data.

Package version

react-instantsearch 7.2.0, remix 2.2.0, algoliasearch 4.20.0

Operating system

No response

Browser

No response

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct

sefai avatar Aug 06 '24 10:08 sefai

Thanks for that addition, this indeed can be solved by ensuring serverState gets computed server side, you don't need to use the same InstantSearch component, but of course the same widgets need to be mounted backend as frontend. For now I'll close this issue then

Haroenv avatar Aug 06 '24 11:08 Haroenv