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

React中使用useState赋值时请求payload为空的问题排查

问题分析与修复方案

React组件(Compare.js)核心问题

  1. useCallback依赖缺失:fetchData用useCallback包裹但依赖数组为空,导致它始终引用初始状态的compare(空值),请求时body里的proId1和proId2都是空字符串。
  2. 错误的事件处理写法:按钮onClick里嵌套useEffect违反React规则,useEffect只能在组件顶层调用;同时未阻止表单默认提交行为,会导致页面刷新。
  3. 未处理请求结果:fetchData返回数据后未存入状态,无法传递给Result组件展示。

修改后的Compare.js代码

import React, { useState, useCallback } from "react";
import Result from "./Result";

export default function Compare() {
  const [compare, setCompare] = useState({
    proId1: "",
    proId2: "",
  });
  const [resultData, setResultData] = useState([]); // 新增状态存储查询结果

  function handleChange(event) {
    const { value, name } = event.target;
    setCompare((prevData) => ({
      ...prevData,
      [name]: value,
    }));
  }

  // 补全依赖数组,确保捕获最新的compare状态
  const fetchData = useCallback(async () => {
    const response = await fetch("http://localhost:3000/api/compare", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        proId1: compare.proId1,
        proId2: compare.proId2,
      }),
    });

    const data = await response.json();
    setResultData(data); // 将结果存入状态,传递给Result组件
  }, [compare]);

  // 处理表单提交,阻止默认行为并调用fetchData
  const handleSubmit = async (e) => {
    e.preventDefault();
    await fetchData();
  };

  return (
    <>
      <div>
        <h1>ENTER IDS TO COMPARE</h1>
        {/* 绑定表单onSubmit事件,替代按钮onClick */}
        <form onSubmit={handleSubmit}>
          <input
            type="text"
            className="proId1"
            placeholder="proId1"
            name="proId1"
            onChange={handleChange}
            value={compare.proId1}
          />
          <input
            type="text"
            className="proId2"
            placeholder="proId2"
            name="proId2"
            onChange={handleChange}
            value={compare.proId2}
          />
          <button className="submit" type="submit">SUBMIT</button>
        </form>
      </div>
      {/* 将查询结果传递给Result组件 */}
      <Result data={resultData} />
    </>
  );
}

服务器端代码问题

req.body.proId1和req.body.proId2是同步数据,不需要用await,多余的await会导致变量变为Promise对象,MongoDB无法匹配到数据。

修改后的服务器代码

app.post("/api/compare", async (req, res) => {
  try {
    // 去掉多余的await
    const id1 = req.body.proId1;
    const id2 = req.body.proId2;
    const result = await model.find({ id: { $in: [id1, id2] } });
    res.send(result);
  } catch (error) {
    res.json({ status: "error", error: error.message }); // 返回具体错误信息便于调试
  }
});

额外注意事项

  • 确保Express服务器配置了解析JSON请求的中间件:app.use(express.json());,否则req.body会是undefined。
  • Result组件需接收data属性并渲染结果,示例如下:
export default function Result({ data }) {
  return (
    <div>
      <h2>Comparison Result</h2>
      {data.length > 0 ? (
        <div>
          {data.map(item => (
            <div key={item._id}>
              <p>ID: {item.id}</p>
              <p>Name: {item.name}</p>
              <p>Price: {item.price}</p>
              <p>Ratings: {item.ratings}</p>
            </div>
          ))}
        </div>
      ) : (
        <p>No data found</p>
      )}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:40:24