DynamicWidgets does not work with Remix Link
dziugas-liaudinskas opened this issue · comments
🐛 Current behavior
When the component which is passed to the getServerState
method contains DynamicWidgets
and Link
from “@remix-run/react” components it causes the app to break with the error: “useHref() may be used only in the context of a component.”. If DynamicWidgets
or Link
is removed then everything seems fine
🔍 Steps to reproduce
- Go to https://codesandbox.io/p/sandbox/lucid-cerf-glr0tu
- Everything should work fine, you can see filters and hits
- In
app/components/Search.tsx
change line 97 from<Hits hitComponent={Hit} />
to<Hits hitComponent={HitWithLink} />
(same component just wrapped with Link) - "Error: useHref() may be used only in the context of a component."
- Now delete
<DynamicWidgets>
, refresh and the app is working again (just without filters)
Live reproduction
https://codesandbox.io/p/sandbox/lucid-cerf-glr0tu
💭 Expected behavior
DynamicWidgets should work with Remix Link
Package version
react-instantsearch-hooks-web 6.41.0, react-instantsearch-hooks-server 6.41.0
Operating system
macOS
Browser
Chrome
Code of Conduct
- I agree to follow this project's Code of Conduct
Hi, in getServerState()
when we detect a dynamic widget we run renderToString
on your search component a second time to get the initial state of all the dynamic facets we received from Algolia. This time, apparently the router context is lost, which creates the error you see.
We'll look at if and how we can fix that, but in the meantime, you can conditionally wrap your Hit component with a Link, depending on whether you detect a router context or not. Here's an example:
import { useInRouterContext } from 'react-router';
/* ... */
function HitWithLink({ hit }: HitProps) {
const inRouterContext = useInRouterContext();
const Hit = () => (
<>
<Highlight hit={hit} attribute="name" className="Hit-label" />
<span className="Hit-price">${hit.price}</span>
</>
);
if (inRouterContext) {
return (
<Link to="/new">
<Hit />
</Link>
);
}
return <Hit />;
}