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

React项目使用SendGrid实现联系表单的报错解决请求

问题解决:React中使用SendGrid实现联系表单的编译错误与类型检查问题

一、解决"Can't resolve 'fs'"编译错误

这个错误的核心原因是SendGrid是服务端(Node.js)专用包,不能在浏览器环境的React代码中直接引入。浏览器没有fs、path这类Node.js内置模块,只要客户端代码里import了@sendgrid相关包,就会触发这个错误。

解决步骤:

  • 检查card.tsx和Contact.tsx,删除所有import '@sendgrid/mail'或其他SendGrid相关的导入语句。
  • 确保所有SendGrid的邮件发送逻辑都只存在于server.js中,客户端仅负责收集表单数据并通过HTTP请求发送给后端接口。

示例代码调整

客户端(card.tsx/Contact.tsx):仅保留表单UI和请求逻辑

// Contact.tsx
import { useState } from 'react';

// 定义表单数据类型,解决类型检查问题
interface ContactFormData {
  name: string;
  email: string;
  message: string;
}

export default function Contact() {
  const [formData, setFormData] = useState<ContactFormData>({
    name: '',
    email: '',
    message: ''
  });

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    try {
      const response = await fetch('/api/send-email', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(formData),
      });
      if (response.ok) {
        alert('邮件发送成功!');
        setFormData({ name: '', email: '', message: '' });
      } else {
        throw new Error('邮件发送失败');
      }
    } catch (err) {
      console.error(err);
      alert('发送出错,请稍后重试');
    }
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        name="name"
        value={formData.name}
        onChange={handleChange}
        placeholder="你的姓名"
        required
      />
      <input
        type="email"
        name="email"
        value={formData.email}
        onChange={handleChange}
        placeholder="你的邮箱"
        required
      />
      <textarea
        name="message"
        value={formData.message}
        onChange={handleChange}
        placeholder="留言内容"
        required
      />
      <button type="submit">发送</button>
    </form>
  );
}

服务端(server.js):处理SendGrid邮件发送

// server.js
const express = require('express');
const sgMail = require('@sendgrid/mail');
const app = express();

// 配置SendGrid API密钥
sgMail.setApiKey(process.env.SENDGRID_API_KEY);

// 解析JSON请求体
app.use(express.json());

// 邮件发送接口
app.post('/api/send-email', async (req, res) => {
  const { name, email, message } = req.body;
  const msg = {
    to: '你的目标邮箱@example.com', // 接收邮件的邮箱(需在SendGrid后台验证)
    from: email, // 发件人邮箱(需在SendGrid后台验证)
    subject: `来自${name}的联系留言`,
    text: message,
    html: `<p>姓名:${name}</p><p>邮箱:${email}</p><p>留言:${message}</p>`,
  };

  try {
    await sgMail.send(msg);
    res.status(200).json({ success: true });
  } catch (error) {
    console.error(error);
    res.status(500).json({ success: false, error: error.message });
  }
});

// 启动服务器
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

二、解决Contact.tsx的类型检查问题

常见类型问题的解决方式:

  • 表单数据无类型定义:像示例中定义ContactFormData接口,明确约束表单字段的类型。
  • 事件处理函数类型错误:给handleSubmit指定React.FormEvent<HTMLFormElement>类型,给handleChange指定React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>类型,避免TypeScript报错。
  • 未初始化的状态变量:用useState<ContactFormData>明确状态类型,确保初始值符合接口定义。

三、项目运行注意事项

  1. 先启动后端服务:运行node server.js(推荐安装nodemon实现热重载,命令为nodemon server.js)。
  2. 配置React代理:在React项目的package.json中添加"proxy": "http://localhost:5000",让客户端请求自动转发到后端服务。
  3. 配置环境变量:在服务端根目录创建.env文件,添加SENDGRID_API_KEY=你的SendGrid密钥,安装dotenv包(npm install dotenv)并在server.js顶部引入require('dotenv').config()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 10:35:01