@lucianojd/recoil-sync-next
Version:
recoil-sync stores for Next.js
44 lines (43 loc) • 1.87 kB
JavaScript
import { useRouter } from 'next/router';
import { useCallback, useEffect, useRef } from 'react';
export function useSyncURLNext({ shallow, }) {
const { isReady, asPath, replace, push, events } = useRouter();
const urlRef = useRef({
path: isReady ? asPath : '/',
needNotify: !isReady,
handler: undefined,
});
const { needNotify, handler } = urlRef.current;
useEffect(() => {
if (isReady && needNotify && handler) {
urlRef.current.path = asPath;
urlRef.current.needNotify = false;
handler();
}
}, [isReady, needNotify, handler, asPath]);
const updateURL = useCallback((url) => {
urlRef.current.path = url;
}, []);
const browserInterface = {
replaceURL: useCallback((url) => replace(url, undefined, { shallow }), [replace, shallow]),
pushURL: useCallback((url) => push(url, undefined, { shallow }), [push, shallow]),
getURL: useCallback(() => {
var _a, _b, _c;
const url = new URL(urlRef.current.path, (_c = (_b = (_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.document) === null || _a === void 0 ? void 0 : _a.location) === null || _b === void 0 ? void 0 : _b.href) !== null && _c !== void 0 ? _c : 'http://localhost:3000');
return url.toString();
}, []),
listenChangeURL: useCallback((handler) => {
urlRef.current.handler = handler;
events.on('routeChangeStart', updateURL);
events.on('routeChangeStart', handler);
return () => {
events.off('routeChangeStart', handler);
events.off('routeChangeStart', updateURL);
urlRef.current.handler = undefined;
};
}, [events, updateURL]),
};
return {
browserInterface,
};
}