React应用中fetch()方法未正常触发调用的问题求助
问题描述
我正在参考教程学习,经排查判断App.js文件中的fetch()方法未被正常调用。以下是项目相关代码,这是我第一次独立编写React应用。
原有代码
App.js
import React, { useState } from "react"; import "./App.css"; function App() { const makeOrder = () => { fetch("/api/order", { method: "POST", headers: { "Content-Type": "application/json", }, body: "Helllloooo!", }).then((response) => response.json()); }; return ( <div className="App"> <header className="App-header"> <h1>Markee</h1> <button type="button" class="btn btn-primary" onClick={makeOrder}> Send </button> </header> </div> ); } export default App;
pages/api/order.js
// pages/api/order.js import sendSMS from "../../utils/twilio"; alert("happened"); const handler = async (request, response) => { switch (request.method) { case "POST": await sendSMS("xxxxxxxx", "Hooola!"); alert("this happened"); response.status(200).json({ message }); break; default: response.status(405).end("This method is not allowed for this route."); alert("that happened"); } }; export default handler;
utils/twilio.js
import twilio from "twilio"; alert("happened adda"); const accountSid = "xxxxxxxxxx"; const authToken = "xxxxxxxxxx"; const client = require("twilio")(accountSid, authToken); const sendSMS = async (recipient, message) => { return await client.messages .create({ mediaUrl: [ "https://images.unsplash.com/photo-1545093149-618ce3bcf49d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=668&q=80", ], from: "whatsapp:xxxxxxx", to: recipient, body: message, }) .then((message) => console.log(message.sid)); }; export default twilio;
问题原因&修复方案
代码里有6个直接导致功能失效的错误:
- JSX语法错误:React的JSX中不能使用原生HTML的
class属性,和JS关键字冲突,必须替换为className。原有按钮上的class="btn btn-primary"会导致JSX编译/渲染异常,点击事件无法正常绑定。 - 运行环境API混用:
alert()是浏览器端专属全局API,pages/api下的代码运行在Node.js服务端,根本不存在alert对象,代码运行到alert位置会直接抛出异常,导致接口崩溃,请求无法正常响应。 - 导出错误:
twilio.js中定义了发送短信的sendSMS方法,但最后导出的是导入的twilio依赖库,导致order.js中引入的sendSMS根本不是发送短信的函数,调用直接报错。 - 未定义变量:
order.js中返回响应时使用了未声明的message变量,会抛出引用错误,导致接口无法正常返回响应。 - 请求格式错误:fetch请求头中声明了
Content-Type: application/json,但请求体传的是纯字符串,不是合法JSON格式,后端解析请求体会直接报错。 - 缺少错误捕获:fetch调用没有添加catch错误捕获,接口报错时前端控制台不会打印明确错误信息,难以排查问题。
修复后代码
App.js
import React, { useState } from "react"; import "./App.css"; function App() { const makeOrder = () => { fetch("/api/order", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ content: "Helllloooo!" }), }) .then((response) => { if (!response.ok) { throw new Error(`请求异常,状态码:${response.status}`); } return response.json(); }) .then(data => console.log("请求成功", data)) .catch(err => console.error("请求失败:", err)); }; return ( <div className="App"> <header className="App-header"> <h1>Markee</h1> <button type="button" className="btn btn-primary" onClick={makeOrder}> Send </button> </header> </div> ); } export default App;
pages/api/order.js
import sendSMS from "../../utils/twilio"; const handler = async (request, response) => { switch (request.method) { case "POST": try { await sendSMS("xxxxxxxx", "Hooola!"); const message = "短信发送成功"; response.status(200).json({ message }); } catch (err) { console.error("短信发送失败:", err); response.status(500).json({ message: "服务内部错误" }); } break; default: response.setHeader("Allow", ["POST"]); response.status(405).end("This method is not allowed for this route."); } }; export default handler;
utils/twilio.js
import twilio from "twilio"; const accountSid = "xxxxxxxxxx"; const authToken = "xxxxxxxxxx"; const client = twilio(accountSid, authToken); const sendSMS = async (recipient, message) => { return client.messages.create({ mediaUrl: [ "https://images.unsplash.com/photo-1545093149-618ce3bcf49d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=668&q=80", ], from: "whatsapp:xxxxxxx", to: recipient, body: message, }); }; export default sendSMS;
改完后重启前端开发服务和Node服务,点击Send按钮时同时观察浏览器控制台、服务端终端的日志,就能看到请求的完整执行状态了。
内容的提问来源于stack exchange,提问作者Hammad Nasir
相关产品推荐
相关产品推荐

