-
-
Notifications
You must be signed in to change notification settings - Fork 154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using useSearch
with SSR throws a hydration warning
#446
Comments
Looks like this is the reason 🤔
|
Not sure if you are accepting new code, based on the last open PRs |
We are accepting new code! The current open PRs are quite difficult to merge, since there were intended for v2, but I stopped adding new features when I was working on v3 release. I think these PRs have to be closed unfortunately and reimplemented from scratch. Your contributions are always welcome! |
Oh cool! I'll work on a fix this weekend :D |
Hi! I created this as a "hotfix" locally - just works™️ import { IS_BROWSER } from 'powership';
function parseLocationEntries() {
return [
['path', window.location.pathname],
['search', window.location.search],
] as const;
}
export type LocationEntry = ReturnType<typeof parseLocationEntries>;
export type RouteChangeCallback = (changes: LocationEntry) => void;
const subscribers = new Set<RouteChangeCallback>();
if (IS_BROWSER) {
let current = parseLocationEntries();
const callback = () => {
if (!subscribers.size) return;
const next = parseLocationEntries();
const changed = next.filter((el, idx) => el[1] !== current[idx][1]);
if (!changed.length) return;
current = next;
subscribers.forEach((fn) => {
fn(current);
});
};
const events = ['popstate', 'pushState', 'replaceState', 'hashchange'];
for (const event of events) {
addEventListener(event, callback);
}
}
export function observeRouteChange(cb: RouteChangeCallback) {
subscribers.add(cb);
return () => {
subscribers.delete(cb);
};
} // example
function useRoute() {
const router = useWouter();
const [route, setRoute] = React.useState(() => {
return {
search: router.ssrSearch || '',
path: router.ssrPath || '',
};
});
useEffect(() => {
return observeRouteChange((changes) => {
setRoute((state) => {
changes.forEach(([k, v]) => {
state = { ...state, [k]: v };
});
return state;
});
});
}, []);
return route;
} edit: removed startTransition |
How to reproduce:
<Router ssrPath={requestUrl.pathname} ssrSearch={requestUrl.search}>
<Router />
Expected: when wouter runs in the browser, by default it should fill in
ssrPath
andssrSearch
with current pathname and search string extracted fromlocation
The text was updated successfully, but these errors were encountered: