Storing page data with history api or with next/router #14203
Unanswered
stevekanger
asked this question in
Help
Replies: 1 comment 1 reply
-
I've implemented something similar for ecoeats. Changes to a subset of settings (stored in a local GQL query) get synced to the URL on change. It does require encoding state into the URL, but this works out well for our use case. You could modify this code to persist as base64 in order to keep stuff like scroll position kept obscured. import { useApolloClient, useQuery } from "@apollo/react-hooks";
import { useRouter } from "next/router";
import { useEffect, useRef } from "react";
import { SETTINGS } from "../graphql/queries";
function parseQuery(queryString) {
var query = {};
var pairs = (queryString[0] === "?"
? queryString.substr(1)
: queryString
).split("&");
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split("=");
if (pair[0] === "") continue;
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
}
return query;
}
/**
* A hook that syncs changes from local state to the URL
* to provide persistence. Syncs only changes defined in the
* SETTINGS query and doesn't mess with others.
*/
export const useURLSync = () => {
const router = useRouter();
const { data } = useQuery(SETTINGS);
const firstLoad = useRef(true);
const client = useApolloClient();
useEffect(() => {
if (!(process as any).browser) return;
const query = parseQuery(window.location.search.slice(1));
if (firstLoad.current) {
// First load, so sync one way
client.writeQuery({
query: SETTINGS,
data: {
...query,
},
});
firstLoad.current = false;
return;
}
const updateQuery = (newQuery) => {
router.push(
{
pathname: router.pathname,
query: { ...newQuery },
},
{
pathname: `/places/${router.query.zone}`,
query: { ...newQuery },
},
{
shallow: true,
}
);
};
if (Object.entries(data).every(([k, v]) => query[k] === v)) {
return;
}
const newQuery = Object.assign(query, data);
updateQuery(newQuery);
}, [client, data, router, router.query]);
}; |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I am trying to implement custom scrolling functionality. When a user navigates away from the page I want to store the scroll position of the page so I can restore it when they return with back and forward buttons. Next/router doesn't provide any type of history and every time I try to save to the window.history 's state next/router overwrites this data. It seems as though they have taken away functionality that should be available with no alternative.
I either need to have a reference to each page like an id or something so I can store scroll data in my own state or be able to store data in the window.history state. I don't see any way to achieve this with next/router.
I am trying to store data on routechangestart and retrieve it on routechangecomplete like so:
I have also tried setting the data to options in the state I think that is what the following discussion was about #5918 but I get really inconsistent results.
Beta Was this translation helpful? Give feedback.
All reactions