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

Next.js中Select选择值收集失败,点击按钮无响应问题排查

问题修复方案

前端页面(page.jsx)问题修复

  1. 初始化useRouter:组件内仅导入useRouter但未实例化,导致router.push报错
  2. 替换请求方法:GET请求不支持携带body参数,改为POST传递筛选条件
  3. 正确解析响应:需先调用await res.json()获取响应体,不能直接访问res.data
  4. 修正提示逻辑:成功状态改用成功提示,避免错误提示混淆
  5. 恢复表单校验:启用空值校验,防止无效提交

修改后的page.jsx代码:

"use client";

import { useRouter } from "next/navigation";
import { useState } from "react";
import { useSession } from "next-auth/react";
import { toast } from "react-toastify";
import { Select, Option } from "@material-tailwind/react";

const Selectt = () => {
  const [subject, setSubject] = useState("");
  const [grade, setGrade] = useState("");
  const [show, setShow] = useState(false);
  // 初始化router实例
  const router = useRouter();

  const handleSelect = async () => {
    // 校验必填项
    if (!subject || !grade ) {
      toast.error("Hãy chọn đầy đủ các mục!");
      return;
    }

    try {
      const res = await fetch("/api/quiz/FilterQuestion", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ subject, grade }),
      });

      const responseData = await res.json();

      if (res.status === 400) {
        toast.error("Không tồn tại câu hỏi thỏa mãn", {
          position: toast.POSITION.TOP_CENTER,
          className: "foo-bar",
        });
        router.push("/thithu");
      } else if (res.status === 201) {
        console.log(responseData.data[0]);
        router.push("/home");
        toast.success("Có câu hỏi thỏa mãn!");
      } else {
        router.push("/blog");
        toast.error("Quá khó!");
      }
    } catch (error) {
      toast.error(error.message);
    }
  };

  return (
    <>
      <div className={`${show?'pointer-events-none opacity-0':''} flex flex-row items-center justify-center w-1/2 gap-10 m-auto`}>
        <Select
          label="Chọn môn"
          color="purple"
          animate={{ mount: { y: 0 }, unmount: { y: 25 } }}
          value={subject}
          onChange={(subject) => setSubject(subject)}
        >
          <Option value="math">Toán</Option>
          <Option value="physics">Vật lí</Option>
          <Option value="chemistry">Hóa học</Option>
        </Select>

        <Select
          label="Chọn lớp"
          color="blue"
          animate={{ mount: { y: 0 }, unmount: { y: 25 } }}
          value={grade}
          onChange={(grade) => setGrade(grade)}
        >
          <Option value="9">Lớp 9</Option>
          <Option value="10">Lớp 10</Option>
          <Option value="11">Lớp 11</Option>
          <Option value="12">Lớp 12</Option>
        </Select>
      </div>
      <div className="flex m-auto">
        <button 
          className={`${show?'pointer-events-none opacity-0 text-none':''}bg-green-200 mt-3 p-2 rounded-md m-auto`}
          onClick={handleSelect}
        >
          Select
        </button>
      </div>
    </>
  );
};

export default Selectt;

后端API(route.js)问题修复

  1. 对应请求方法:将GET改为POST,匹配前端请求
  2. 异步获取查询结果:find()是异步方法,必须加await才能拿到真实数据
  3. 正确判断结果存在性:通过数组长度判断是否有匹配数据,而非直接判断对象
  4. 修正响应写法:使用NextResponse.json()正确生成JSON响应
  5. 统一异常处理:将数据库查询逻辑放入try块,捕获并处理查询错误

修改后的route.js代码:

import Question from "models/Question";
import connectDB from "config/question_database";
import { NextResponse } from "next/server";

export const POST = async (request) => {
  try {
    await connectDB();
    const { subject, grade} = await request.json();
    console.log(subject, grade);

    // 等待查询结果返回
    const selectedQuestion = await Question.find({
      subject: subject, 
      class: grade
    });

    // 检查是否有匹配数据
    if (selectedQuestion.length === 0) {
      console.log("Không tồn tại câu hỏi thỏa mãn");
      return NextResponse.json(
        { error: "Không tồn tại câu hỏi thỏa mãn yêu cầu" }, 
        { status: 400 }
      );
    } else {
      console.log("Thành công");
      return NextResponse.json(
        { data: selectedQuestion }, 
        { status: 201 }
      );
    }
  } catch (error) {
    console.error("Lỗi truy vấn cơ sở dữ liệu:", error);
    return NextResponse.json(
      { error: "Lỗi khi xử lý yêu cầu" }, 
      { status: 500 }
    );
  }
};

核心问题总结

  • HTTP GET请求不支持携带body参数,改用POST才能正确传递筛选条件
  • MongoDB的find()是异步操作,必须使用await获取实际查询结果
  • 前端未初始化router实例导致页面跳转功能失效
  • 响应数据处理错误,需先解析JSON才能访问返回内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:38:09