reactjs - 导航客户端时在 NextJS 中保留查询字符串参数

标签 reactjs next.js

使用 nextjsnext-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回到路由器,我丢失了查询字符串参数。

我尝试了其他几种变体,但不幸的是我找不到正确的实现。

任何帮助表示赞赏。

最佳答案

经过一番搜索,我设法得到了我想要的结果,如下所示:

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("&");
}

关于reactjs - 导航客户端时在 NextJS 中保留查询字符串参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54560660/

相关文章:

javascript - Reactjs类型错误: Class extends value undefined is not a constructor or null

javascript - React 使用 setState 更新书架

javascript - 成功登录后重定向或在下一个身份验证中注册凭据类型

next.js - 创建 paymentIntent 并使用 stripe 存储 clientSecret 的最佳实践

javascript - 通过 API PUT 删除换行符将文本区域保存到数据库

reactjs - 在另一个组件中 React Router Dom Link

javascript - 如何在 React + Typescript 中将状态更新到之前的状态

javascript - 我正在尝试使用 next.js 转换我现有的 react 应用程序。这是正确的做法吗?

reactjs - 如何在 react-markdown 中使用自定义组件

node.js - 使用 `useLocalStorage` 和 `useDebounce` 时如何解决 Next.js 中的 react-hydration-error