You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13保留现有查询参数添加新参数的实现问题

问题分析与解决

你的代码核心问题是:仅修改了URLSearchParams对象,但没有调用Next.js Router的导航方法来更新浏览器URL,所以参数不会在地址栏中显示。

修复步骤

1. 实时获取最新查询参数

不要在组件顶层初始化newSearchParams,而是在handleChange事件中,每次基于当前最新的searchParams创建新实例,确保拿到的是当前地址栏的最新参数状态。

2. 调用Router更新URL

修改参数后,使用router.push方法,将当前路径名(pathname)和新的查询参数拼接后传入,触发浏览器URL更新。

3. 适配品牌多选逻辑(可选优化)

如果需要支持多选品牌,建议将tab参数改为逗号分隔的字符串形式,避免覆盖已选品牌,同时同步复选框的选中状态。

修改后的完整代码

"use client";
import { useEffect, useState } from "react";
import Accordion from "../accordion/accordion";
import { useRouter, usePathname, useSearchParams } from "next/navigation";
import { getBrandsRequest } from "../../../APIRequest/brand/brandApi";
import capitalizeFLetter from "../../../utils/capitalizedFirstWord/capitalizedFirstWord";

const Brand = () => {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [allBrand, setAllBrand] = useState([]);

  const handleChange = (e) => {
    const brandName = e.target.value;
    // 基于当前最新的searchParams创建新实例
    const newSearchParams = new URLSearchParams(searchParams);

    if (e.target.checked) {
      // 多选逻辑:添加品牌到tab参数(逗号分隔)
      const existingTabs = newSearchParams.get("tab")?.split(",") || [];
      if (!existingTabs.includes(brandName)) {
        existingTabs.push(brandName);
        newSearchParams.set("tab", existingTabs.join(","));
      }
    } else {
      // 取消选择时移除对应品牌
      const existingTabs = newSearchParams.get("tab")?.split(",") || [];
      const updatedTabs = existingTabs.filter(tab => tab !== brandName);
      if (updatedTabs.length > 0) {
        newSearchParams.set("tab", updatedTabs.join(","));
      } else {
        // 无选中品牌时删除tab参数
        newSearchParams.delete("tab");
      }
    }

    // 更新URL,保留原有路径和新参数
    router.push(`${pathname}?${newSearchParams.toString()}`);
  };

  useEffect(() => {
    (async () => {
      const data = await getBrandsRequest();
      setAllBrand(data);
    })();
  }, []);

  // 根据URL参数初始化复选框选中状态
  const getCheckedStatus = (brandName) => {
    const existingTabs = searchParams.get("tab")?.split(",") || [];
    return existingTabs.includes(brandName);
  };

  const content = (
    <>
      {allBrand?.map((item, index) => (
        <div className="flex items-center gap-x-2" key={index}>
          <label className="dark:text-white sm:text-[14px] flex items-center">
            <input
              className="w-4 sm:w-3 h-4 mr-2 accent-[#ff007f]"
              name={item?.name}
              onChange={handleChange}
              type="checkbox"
              value={item?.name}
              checked={getCheckedStatus(item?.name)}
            />
            {capitalizeFLetter(item?.name)}
          </label>
        </div>
      ))}
    </>
  );

  return (
    <div className=" max-w-[275px] px-5 border border-gray-200 rounded-lg shadow card w-96 bg-base-100 bg-white dark:bg-gray-700">
      <Accordion title="Brand" content={content} />
    </div>
  );
};

export default Brand;

关键修改点说明

  • 在handleChange中实时基于当前searchParams创建新实例,避免使用过时的参数。
  • 通过router.push将新参数拼接到路径后,触发URL更新。
  • 新增多选逻辑,支持添加/移除品牌,同时根据URL参数同步复选框选中状态。
  • 删除组件顶层的newSearchParams变量,避免参数状态不一致。

内容的提问来源于stack exchange,提问作者Md Nurullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:49:53