在nextjs
中使用next-routes
,在页面之间导航时是否可以保留URL的查询字符串?我正在运行一个广告系列,出于历史原因和跟踪目的,我在浏览页面时需要保留它。
我无法将其填充到Redux存储或localhost,sessionstorage等中。它必须保留在URL中。
我尝试了以下操作:
import { Router } from 'routes';
Router.events.on('routeChangeStart', (url: string) => {
if (Router.query && Router.router.pathname !== url) {
const href = `${url}${Object.keys(Router.query).reduce(
(carry: string, key: string) => {
carry += `${carry === '' ? '?' : '&'}${key}=${Router.query[key]}`;
return carry;
},'')}`;
Router.pushRoute(href, Router.router.pathname, { shallow: true });
}
});
然后routes.js
文件导出next-routes
:
const nextRoutes = require('next-routes');
const routes = (module.exports = nextRoutes());
这里发生的是正确推送了URL,并且查询字符串仍然存在,但仅是短暂的闪烁。它将立即将原始url
推回路由器,而我丢失了查询字符串参数。
我尝试了其他几种变体,但不幸的是我找不到正确的实现。
感谢您的帮助。
答案 0 :(得分:1)
在进行一些搜索之后,我设法获得了以下结果:
const customRouter = (module.exports = nextRoutes());
customRouter.Router.pushRouteWithQuery = function(route, params, options) {
if(!params || !Object.keys(params).length) {
const routeWithParams = QueryStringHelper.generateUrlWithQueryString(route, customRouter.Router.router.query);
customRouter.Router.pushRoute(routeWithParams, params, options);
} else {
const filteredParams = QueryStringHelper.filterAllowedParams(customRouter.Router.router.query);
const allParams = {
...filteredParams,
...params
};
customRouter.Router.pushRoute(route, allParams, options);
}
}
然后我将使用新创建的方法使用所需的查询字符串重定向到另一页:
import { Router } from 'my/module'
Router.pushRouteWithQuery('/home');
最后是QueryStringHelper
:
module.exports = {
generateUrlWithQueryString,
getAllowedParams,
prepareParamsAsQueryString,
filterAllowedParams
}
function getAllowedParams() {
const allowedParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'mid', 'gclid', 'source'];
return allowedParams;
}
function prepareParamsAsQueryString() {
const params = getAllowedParams();
let paramsLikeQueryString = [];
for (let index = 0; index < params.length; index++) {
const param = params[index];
paramsLikeQueryString.push(`${param}=:${param}?`);
}
return paramsLikeQueryString.join('&');
}
function generateUrlWithQueryString(url, params) {
if(Object.keys(params).length) {
const filteredParams = filterAllowedParams(params);
if (Object.keys(filteredParams).length) {
if(url[0] != '/')
url = `/${url}`;
return `${url}?${serialize(filteredParams)}`;
}
return url;
}
return url;
}
function filterAllowedParams(params) {
if(Object.keys(params).length) {
const filteredParams = Object.keys(params)
.filter(key => getAllowedParams().includes(key.toLowerCase()))
.reduce((obj, key) => {
obj[key] = params[key];
return obj;
}, {});
return filteredParams;
}
return params;
}
// INTERNAL
function serialize(obj) {
var str = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
}
答案 1 :(得分:0)
我从 URL 中获取了查询字符串,并在我使用组件的任何地方将其传递了很长时间。
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
export const getUrlPathParams = (): string => {
const [pathParams, setPathParams] = useState("");
useEffect(() => {
setPathParams(router?.asPath?.slice(router?.pathname?.length));
});
const router = useRouter();
return pathParams;
};
以及在链接中使用它的示例。
<Link href={"/" + getUrlPathParams()}> Home </Link>
我对我的外部链接做同样的事情,以便我的广告活动有效。