GSSP ajax-mode -- HYDRATE-action not dispatching
chiralium opened this issue · 0 comments
chiralium commented
Describe the bug
When use navigate the page by shallow routing and use back/forward browser button, library not call HYDRATE-action and url is change but state is not.
To Reproduce
- Create page that containing for example pagination
- The page number changed by url-parameter
?page
via:
await Router.push({
query: {
...Router.query,
page: newPage,
}
}, undefined, {shallow: true});
- Click on pagination button is ok, but click to native back/forward-button in browser have no effect: the GSSP-function is called by Next.Js (ajax-request is sent) but redux state not changed at all.
Expected behavior
Library change the state via back/fowrad history transtion
Additional context
I fix the issue by adding custom hook:
import { useRouter } from 'next/router';
import { HYDRATE } from 'next-redux-wrapper';
import { useCallback, useEffect, useState } from 'react';
import { useAppDispatch } from 'src/redux/hooks/useAppDispatch';
import { TAppRootState } from 'src/redux/types';
export const useHistoryHydration = (state: TAppRootState) => {
const router = useRouter();
const dispatch = useAppDispatch();
const [isHistoryTransition, setIsHistoryTransition] = useState<boolean>(false);
const handleHistoryChange = useCallback(() => {
if (!isHistoryTransition) {
return true;
}
dispatch({
payload: state,
type: HYDRATE,
});
setIsHistoryTransition(false);
return true;
}, [dispatch, isHistoryTransition, state]);
useEffect(() => {
router.events.on('routeChangeComplete', handleHistoryChange);
// eslint-disable-next-line consistent-return
return () => router.events.off('routeChangeComplete', handleHistoryChange);
}, [handleHistoryChange, isHistoryTransition, router.events, router.isReady]);
useEffect(() => {
router.beforePopState(({ url, as, options }) => {
if (options.shallow) {
router.replace(url, as, { ...options, shallow: false });
return false;
}
setIsHistoryTransition(true);
return true;
});
}, [router]);
};
and using it like this:
export type TNextPageProps = {
store: TAppStore;
};
const Catalog: React.FC<TNextPageProps> = ({ store }) => {
useHistoryHydration(store.getState());
// ...