使用 next/router 添加具有相同键的多个查询参数

发布于 2025-01-11 05:44:09 字数 534 浏览 1 评论 0原文

我正在使用 Next.js 应用程序中的查询参数过滤来自 API 的结果。我想使用 useRouter() 使用相同的密钥推送多个不同的过滤器,因此我的查询参数可能如下所示:

?page=1&skill=html&skill=css&skill=js

我可以将每个参数传递给我的 API 请求。现在,当我尝试添加技能参数时,我使用 router.push 来执行此操作,如下所示:

const router = useRouter();

const addFilter = (skill: string) => router.push({ query: { ...router.query, skill: skill.toLowerCase() } });

但显然它会覆盖以前的技能,因此我只得到一个其中的 URL 中。如何使用相同的键添加其他查询参数,最好使用 useRouter()next/router

I'm filtering results from an API utilizing query parameters in my Next.js app. I want to use useRouter() to push multiple different filters with the same key, so my query params could look like:

?page=1&skill=html&skill=css&skill=js

And I can pass each of those parameters to my API request. Right now, when I'm trying to add a skill parameter I'm using router.push to do it, like this:

const router = useRouter();

const addFilter = (skill: string) => router.push({ query: { ...router.query, skill: skill.toLowerCase() } });

But obviously it's overwriting the previous skill, so I'm only ever getting one of them in the URL. How can I go about adding additional query parameters with the same key, preferably using useRouter() or next/router?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

手长情犹 2025-01-18 05:44:09

为了操作 Next.js 中 URL 中的查询参数,我使用了一个自定义钩子,该钩子使用了 useRouter 提供的功能,但我还添加了一些 util 方法,在本例中,为了向 URL 添加过滤器,我有方法 addParam

这是自定义钩子的主体。

const useRouterFilter = () =>{
  const { pathname, query, push } = useRouter()

  return {
    addParam,
    ...
  }
}

这将是挂钩内的 addFilter 方法:

  /**
   * Adds a query param to the URL string. Multiple params with the same name
   * and different values can be added.
   * @param name The name of the param.
   * @param value The value of the param.
   */
  const addParam = (name: string, value: string | boolean | number) => {
    const { [name]: param, ...rest } = query
    let newQuery

    if (!param) {
      newQuery = { ...rest, [name]: encodeURIComponent(value) }
    } else if (Array.isArray(param)) {
      if (param.indexOf(encodeURIComponent(value)) > -1) return
      newQuery = { ...rest, [name]: [...param, encodeURIComponent(value)] }
    } else {
      if (param === encodeURIComponent(value)) return
      newQuery = { ...rest, [name]: [param, encodeURIComponent(value)] }
    }

    push(
      {
        pathname,
        query: newQuery,
      },
      undefined,
      { shallow: true }
    )
  }

在本例中,我使用 push 将参数添加到 URL,但也可以使用 replace

完整的钩子可以从以下要点复制

To manipulate the query params in the URL in Next.js I use a custom hook that uses what useRouter offers, but I also add some util methods, in this case, to add a filter to the URL I have the method addParam.

This is the body of the custom hook.

const useRouterFilter = () =>{
  const { pathname, query, push } = useRouter()

  return {
    addParam,
    ...
  }
}

And this would be the addFilter method inside the hook:

  /**
   * Adds a query param to the URL string. Multiple params with the same name
   * and different values can be added.
   * @param name The name of the param.
   * @param value The value of the param.
   */
  const addParam = (name: string, value: string | boolean | number) => {
    const { [name]: param, ...rest } = query
    let newQuery

    if (!param) {
      newQuery = { ...rest, [name]: encodeURIComponent(value) }
    } else if (Array.isArray(param)) {
      if (param.indexOf(encodeURIComponent(value)) > -1) return
      newQuery = { ...rest, [name]: [...param, encodeURIComponent(value)] }
    } else {
      if (param === encodeURIComponent(value)) return
      newQuery = { ...rest, [name]: [param, encodeURIComponent(value)] }
    }

    push(
      {
        pathname,
        query: newQuery,
      },
      undefined,
      { shallow: true }
    )
  }

In this case I use push to add the parameters to the URL, but replace could also be used.

The full hook can be copied from the following Gist

长不大的小祸害 2025-01-18 05:44:09

您可以先将技能添加到数组中,而不是发送单个值。然后使用 join() 用分隔符分隔值。
例如:

query: { skills: skills.join(",") }

当然你需要在另一边再次爆炸它..

Instead of sending a single value you can add the skills to an array first. And then use join() to separate the values by a separator.
Ex:

query: { skills: skills.join(",") }

And of course you need to explode it again on the other side..

白龙吟 2025-01-18 05:44:09

您可以修改 addFilter 函数,将所需的 skill 值作为数组添加到 skill 查询参数中。确保对数组项进行重复删除,以避免 URL 中出现重复的过滤器。

const convertQueryParamToArray = (queryParam: string) => !queryParam ? [] : [queryParam];

const addFilter = async (skill: string) => {
    // Force `skill` query param into an array
    const currentSkillArray = Array.isArray(router.query.skill)
        ? router.query.skill
        : convertQueryParamToArray(router.query.skill);
    // Deduplicate skills with same value
    const newSkillArray = [...new Set([...currentSkill, skill.toLowerCase()])];
    router.push({
        query: { ...router.query, skill: newSkillArray }
    });
};

给定上述函数并假设您的 URL 以 /?page=1 开头,调用 addFilter('html') 将使 URL 变为 /?page=1& ;技能=html。以下对 addFilter('css') 的调用会将 URL 更新为 /?page=1&skill=html&skill=css。等等。

You can modify your addFilter function to add the desired skill value to the skill query parameter as an array. Making sure to deduplicate the array items, to avoid having repeated filters in the URL.

const convertQueryParamToArray = (queryParam: string) => !queryParam ? [] : [queryParam];

const addFilter = async (skill: string) => {
    // Force `skill` query param into an array
    const currentSkillArray = Array.isArray(router.query.skill)
        ? router.query.skill
        : convertQueryParamToArray(router.query.skill);
    // Deduplicate skills with same value
    const newSkillArray = [...new Set([...currentSkill, skill.toLowerCase()])];
    router.push({
        query: { ...router.query, skill: newSkillArray }
    });
};

Given the above function and assuming your URL starts as /?page=1, calling addFilter('html') would make the URL become /?page=1&skill=html. A following call to addFilter('css') would update the URL to /?page=1&skill=html&skill=css. And so on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文