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

Next.js 10.0.5中使用浅路由(Shallow Routing)更新路由后router.query无法获取最新查询字符串的问题

嘿,我之前在Next.js 10里也踩过这个浅路由的坑!问题出在这几个地方,我帮你捋一捋:

核心问题:闭包陷阱 + 浅路由的渲染特性

你的selectFilter函数被包裹在_.debounce里,又通过useCallback用空依赖数组缓存了下来——这意味着这个debounce函数从组件挂载开始,就一直引用着第一次渲染时的router.query值(也就是初始的undefined),不管你之后怎么更新路由,它拿到的始终是旧值,自然每次都进入else分支。

另外,Next.js的浅路由更新不会触发组件重新渲染,所以router.query不会自动同步到组件的闭包里,必须主动获取最新值。

修复方案

我调整了你的代码,主要解决闭包问题,同时优化浅路由的使用:

const NumberFilter = ({ filter }) => { 
  const router = useRouter() 
  const [value, setValue] = useState('') 
  
  // 用useRef保存debounce函数,避免每次渲染重置延迟
  const selectFilterRef = useRef(_.debounce((inputValue) => {
    // 每次执行时都获取最新的路由参数,避开闭包陷阱
    const currentQuery = { ...router.query };
    const filterSearch = `${filter.id}-${inputValue}-${inputValue}`;
    let filters;

    if (inputValue !== null) {
      const lastQsf = currentQuery['filters'];
      if (Array.isArray(lastQsf)) {
        filters = [...lastQsf, filterSearch];
      } else if (typeof lastQsf === 'string') {
        filters = [lastQsf, filterSearch];
      } else {
        filters = [filterSearch];
      }
    }

    router.push(
      {
        pathname: router.pathname,
        query: { ...currentQuery, filters }
      },
      undefined,
      { shallow: true }
    );
  }, 1000));

  const handleChange = useCallback((inputValue) => {
    selectFilterRef.current(inputValue);
  }, []);

  // 可选:监听路由参数变化,方便后续处理(比如回显筛选值)
  useEffect(() => {
    console.log('最新的查询参数:', router.query);
  }, [router.query]);

  return ( 
    <NumberFormat 
      placeHolder={filter.label} 
      onValueChange={(values)=> { 
        setValue(values.value);
        handleChange(values.value); 
      }} 
      displayType={'number'} 
      value={value} 
      thousandSeparator={true} 
      className="form-control c-form-builder-input mt-15" 
    />
  ) 
}

关键改动说明

  1. 用useRef保存debounce函数:这样组件重新渲染时不会重新创建debounce实例,避免输入时频繁重置延迟时间,同时保证每次执行时能拿到最新的router引用。
  2. 在debounce内部获取最新router.query:直接从router上取当前值,彻底避开闭包带来的旧值问题。
  3. 添加useEffect监听router.query:如果之后需要根据最新的查询参数更新组件状态(比如回显已选的筛选值),这个监听能帮你及时响应路由变化。

这样修改后,你应该就能正常更新查询字符串,并且后续能获取到最新的router.query值了!

内容的提问来源于stack exchange,提问作者Ghazaleh Javaheri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:17:44