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

React与Next.js中如何在router.query后执行GraphQL查询?useQuery传递路由参数触发400错误的求助

解决Next.js中useQuery结合router.query传参的GraphQL 400错误

咱们先拆解你遇到的两个问题:首先是router.query传参导致的400错误,然后再聊聊useLazyQuery的正确用法。

问题1:router.query传参触发GraphQL 400错误的原因

你遇到的400 Bad Request本质是参数类型不匹配:Next.js的router.query返回的所有参数都是字符串类型,但你的GraphQL接口要求taskCategory是数字类型。你手动传数字5时没问题,直接传category(字符串)就会导致接口拒绝请求。

另外还要注意:Next.js在页面初始化阶段(比如SSR/SSG场景),router.query可能是空对象,直接取值会拿到undefined,这也会导致无效参数传递。

解决方案:类型转换 + 控制查询时机

修改你的代码,做两件事:

  1. 把category从字符串转换成数字,同时处理空值情况
  2. 用useQuery的enabled选项,只有当category有效时才执行查询

完整代码示例:

import { useQuery } from '@apollo/client';
import { useRouter } from 'next/router';
import GET_TASKS from '../queries/getTasks'; // 替换成你的查询文件路径

const TaskSingle = () => { 
  const router = useRouter();
  // 转换category为数字,若不存在则设为null
  const category = router.query.category ? Number(router.query.category) : null; 

  const { loading, error, data } = useQuery(GET_TASKS, { 
    variables: { 
      taskFilter: { 
        taskCategory: category,
      }, 
    },
    // 只有当category不为null/undefined时才触发查询
    enabled: !!category,
  }); 

  // 处理加载、错误、空数据状态
  if (loading) return <div>加载中...</div>;
  if (error) return <div>查询出错:{error.message}</div>;
  if (!data?.categories) return <div>未找到相关任务分类</div>;

  return ( 
    <div> 
      {data.categories.map((cat) => (
        <div key={cat.id}>{cat.name}</div>
      ))} 
    </div> 
  );
};

export default TaskSingle;

问题2:useLazyQuery的正确用法

如果你还是想使用useLazyQuery,核心是要手动触发查询,并且监听router.query的变化来执行。这里用useEffect来监听category的变化,当它有效时调用查询函数:

import { useLazyQuery } from '@apollo/client';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import GET_TASKS from '../queries/getTasks';

const TaskSingle = () => { 
  const router = useRouter();
  const category = router.query.category ? Number(router.query.category) : null;
  // useLazyQuery返回查询函数和结果对象
  const [getTasks, { loading, error, data }] = useLazyQuery(GET_TASKS);

  // 当category变化且有效时,触发查询
  useEffect(() => {
    if (category) {
      getTasks({
        variables: {
          taskFilter: { taskCategory: category }
        }
      });
    }
  }, [category, getTasks]); // 依赖项要包含category和getTasks

  // 同样处理状态
  if (loading) return <div>加载中...</div>;
  if (error) return <div>查询出错:{error.message}</div>;
  if (!data?.categories) return <div>未找到相关任务分类</div>;

  return ( 
    <div> 
      {data.categories.map((cat) => (
        <div key={cat.id}>{cat.name}</div>
      ))} 
    </div> 
  );
};

export default TaskSingle;

关键总结

  • 永远记住:router.query的参数全是字符串,一定要根据GraphQL接口要求转换类型(比如转数字、布尔值)
  • 用useQuery的enabled选项可以避免无效的空请求,提升用户体验和减少接口报错
  • useLazyQuery适合需要手动触发的场景(比如点击按钮查询),如果是依赖路由参数自动查询,useQuery + enabled更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 03:57:42