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

NextJs + Router:手动刷新后单选按钮选中状态丢失

解决Next.js筛选组件单选按钮刷新后选中状态丢失问题

问题根源

你的代码核心问题在于使用了非受控属性defaultChecked,它仅在组件首次挂载时生效,页面刷新后组件重新渲染,defaultChecked不会根据更新后的路由参数重新计算,导致选中状态丢失。此外,状态minPrice的同步逻辑没有和单选按钮的选中状态直接绑定,进一步加剧了这个问题。

修复方案

将单选按钮改为受控组件,使用checked属性替代defaultChecked,直接基于路由参数判断选中状态;同时优化路由参数的处理逻辑,确保类型匹配和状态同步。

步骤1:替换defaultChecked为checked

移除defaultChecked,改用checked属性,直接对比router.query.min_price与当前价格区间的min_price(注意类型转换,路由参数默认是字符串)。

步骤2:优化路由参数处理

确保在路由就绪后(router.isReady)再读取参数,避免初始渲染时router.query为空的情况。

修复后的完整代码

const budget = [
  {
    id: "price_1",
    name: "price",
    min_price: 0,
    max_price: 100,
  },
  {
    id: "price_2",
    name: "price",
    min_price: 100,
    max_price: 500,
  },
  {
    id: "price_3",
    name: "price",
    min_price: 500,
    max_price: 1000,
  },
];

export default function Filters() {
  const router = useRouter();

  // 仅在路由就绪时处理参数,避免初始空值
  const currentMinPrice = router.isReady ? router.query.min_price : null;

  return (
    <>
      {budget.map((price) => {
        // 处理类型转换,空值时不选中
        const isChecked = currentMinPrice ? +currentMinPrice === price.min_price : false;
        
        return (
          <div key={price.id} className="form-check mb-2">
            <input
              className="form-check-input"
              type="radio"
              name={price.name}
              id={price.id}
              onChange={(e) =>
                filterProducts(e, {
                  min_price: price.min_price,
                  max_price: price.max_price,
                  filter: 1,
                })
              }
              checked={isChecked}
              value={price.min_price}
            />
            <label className="form-check-label medium" htmlFor={price.id}>
              GHS{price.min_price} - GHS{price.max_price}
            </label>
          </div>
        );
      })}
    </>
  );
}

额外注意事项

  1. 确保filterProducts函数在触发时,正确通过router.push或router.replace更新URL中的min_price参数,例如:
const filterProducts = (e, params) => {
  router.push({
    pathname: router.pathname,
    query: { ...router.query, min_price: params.min_price },
  });
};
  1. 若需要默认选中某个区间(比如第一个),可以在currentMinPrice为空时,设置isChecked为price.min_price === 0(对应第一个区间)。

内容的提问来源于stack exchange,提问作者Kofi Talent

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:10:41