React中使用useState赋值时请求payload为空的问题排查
问题分析与修复方案
React组件(Compare.js)核心问题
- useCallback依赖缺失:
fetchData用useCallback包裹但依赖数组为空,导致它始终引用初始状态的compare(空值),请求时body里的proId1和proId2都是空字符串。 - 错误的事件处理写法:按钮
onClick里嵌套useEffect违反React规则,useEffect只能在组件顶层调用;同时未阻止表单默认提交行为,会导致页面刷新。 - 未处理请求结果:
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
相关产品推荐
相关产品推荐

