mirror of
https://github.com/hsjobeki/noogle.git
synced 2024-09-11 12:59:09 +03:00
improved url entanglement with PageState (#15)
This commit is contained in:
parent
8679af38a2
commit
799cf175a0
@ -1,5 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { NextRouter, useRouter } from "next/router";
|
||||
import {
|
||||
InitialPageState,
|
||||
initialPageState,
|
||||
@ -13,8 +13,9 @@ type PageContextType = {
|
||||
resetQueries: () => void;
|
||||
};
|
||||
|
||||
const initialState = { ...initialPageState, FOTD: true };
|
||||
export const PageContext = React.createContext<PageContextType>({
|
||||
pageState: { ...initialPageState, FOTD: true },
|
||||
pageState: initialState,
|
||||
setPageState: () => {},
|
||||
resetQueries: () => {},
|
||||
setPageStateVariable: function a<T>() {
|
||||
@ -31,31 +32,47 @@ export type SetPageStateVariable = <T>(
|
||||
field: keyof InitialPageState
|
||||
) => (value: React.SetStateAction<T> | T) => void;
|
||||
|
||||
const paramList: Omit<keyof PageState, "data">[] = [
|
||||
"filter",
|
||||
"selected",
|
||||
"term",
|
||||
"page",
|
||||
"itemsPerPage",
|
||||
];
|
||||
const isQueryParam = (key: keyof PageState) => paramList.includes(key);
|
||||
const isInitial = (key: keyof PageState, value: PageState[keyof PageState]) =>
|
||||
JSON.stringify(initialState[key]) === JSON.stringify(value);
|
||||
|
||||
const updateRouter = (router: NextRouter, state: PageState) => {
|
||||
const query = Object.entries(state)
|
||||
.filter(([k]) => isQueryParam(k as keyof PageState))
|
||||
.filter(([k, v]) => !isInitial(k as keyof PageState, v))
|
||||
.reduce((acc, [k, v]) => {
|
||||
return { ...acc, [k]: JSON.stringify(v) };
|
||||
}, {});
|
||||
router.push({ query });
|
||||
};
|
||||
|
||||
export const PageContextProvider = (props: PageContextProviderProps) => {
|
||||
const router = useRouter();
|
||||
const { children, pageProps } = props;
|
||||
const [pageState, setPageState] = useState<PageState>(pageProps);
|
||||
function setPageStateVariable<T>(field: keyof InitialPageState) {
|
||||
return function (value: React.SetStateAction<T> | T) {
|
||||
{
|
||||
if (typeof value !== "function") {
|
||||
setPageState((curr) => {
|
||||
const query = router.query;
|
||||
query[field] = JSON.stringify(value);
|
||||
router.push({ query });
|
||||
return { ...curr, [field]: value };
|
||||
});
|
||||
} else {
|
||||
const setter = value as Function;
|
||||
setPageState((curr) => {
|
||||
const query = router.query;
|
||||
const newValue = setter(curr[field]);
|
||||
query[field] = JSON.stringify(newValue);
|
||||
router.push({ query });
|
||||
|
||||
return { ...curr, [field]: newValue };
|
||||
});
|
||||
}
|
||||
if (typeof value !== "function") {
|
||||
setPageState((curr) => {
|
||||
const newState = { ...curr, [field]: value };
|
||||
updateRouter(router, newState);
|
||||
return newState;
|
||||
});
|
||||
} else {
|
||||
const setter = value as Function;
|
||||
setPageState((curr) => {
|
||||
const newValue = setter(curr[field]);
|
||||
const newState = { ...curr, [field]: newValue };
|
||||
updateRouter(router, newState);
|
||||
return { ...curr, [field]: newValue };
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ export default function FunctionsPage() {
|
||||
const router = useRouter();
|
||||
const [initialProps, setInitialProps] = useState<PageState | null>(null);
|
||||
useEffect(() => {
|
||||
if (router.isReady) {
|
||||
if (router.isReady && initialProps === null) {
|
||||
getInitialProps(router).then((r) => {
|
||||
const { props } = r;
|
||||
console.info("Url Query changed\n\nUpdating pageState with delta:", {
|
||||
@ -55,7 +55,7 @@ export default function FunctionsPage() {
|
||||
setInitialProps((curr) => ({ ...curr, ...props }));
|
||||
});
|
||||
}
|
||||
}, [router]);
|
||||
}, [router, initialProps]);
|
||||
return (
|
||||
<>
|
||||
{!initialProps ? (
|
||||
|
Loading…
Reference in New Issue
Block a user