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

如何通过EmailJS传递React购物车的cartItems状态值?

解决方案

问题核心:emailjs.sendForm()只会抓取表单中带name属性的表单控件(input、textarea等)的值,你页面里的购物车列表是普通DOM元素,所以没法被自动收集。下面给两种可行的实现方式:

方法1:用隐藏输入框传递订单数据

在表单里加一个隐藏的input,把格式化后的购物车数据赋值给它,让sendForm()能抓取到:

修改后的组件代码

import React, { useRef } from 'react';
import emailjs from '@emailjs/browser';
import { useCart } from '../../cart-context';

const EmailOrderForm = () => {
  const { cartItems } = useCart();
  const form = useRef();

  // 把购物车数据格式化为邮件易读的HTML内容
  const formatOrderDetails = () => {
    return cartItems.map(item => `
      <div style="margin: 8px 0; padding-bottom: 8px; border-bottom: 1px solid #eee;">
        <p><strong>商品:</strong>${item.name}</p>
        <p><strong>价格:</strong>${item.price} Kč</p>
      </div>
    `).join('');
  };

  const sendEmail = (e) => {
    e.preventDefault();
    
    // 给隐藏输入框赋值格式化后的订单数据
    const orderInput = form.current.querySelector('[name="order_details"]');
    orderInput.value = formatOrderDetails();

    emailjs
      .sendForm(
        'service_xxxxx',
        'template_xxxxx',
        form.current,
        'XXxxXXxxXXxxXXxx',
      )
      .then(
        () => console.log('SUCCESS!'),
        () => console.log('FAILED!'),
      );
  };

  return (
    <form ref={form} onSubmit={sendEmail}>
      <label>Name</label>
      <input type="text" name="user_name" />
      <label>Email</label>
      <input type="email" name="user_email" />
      <label>Note</label>
      <textarea name="message" />
      
      {/* 新增隐藏输入框,用于传递订单数据 */}
      <input type="hidden" name="order_details" />

      <ul>
        {cartItems.map((item) => (
          <li className="cart-item" key={item.index}>
            <div
              className="cart-item-image"
              style={{
                backgroundImage: `url(${item.image})`,
                width: '100px',
                height: '100px',
                backgroundSize: 'cover',
                backgroundPosition: 'center',
              }}
              alt={item.name}
            ></div>
            <span className="cart-item-name">{item.name}</span>
            <span className="cart-item-price">{item.price}&nbsp;Kč</span>
          </li>
        ))}
      </ul>
      <button className="cart-order" type="submit">
        Order
      </button>
    </form>
  );
};

export default EmailOrderForm;

EmailJS模板配置

在你的EmailJS模板中添加{{order_details}}变量,并且在模板设置里勾选HTML渲染选项,这样邮件会正确解析格式化后的订单内容。

方法2:使用emailjs.send()直接传递参数(更灵活)

放弃依赖表单的sendForm(),改用send()方法直接构造包含所有数据的对象,不需要依赖表单控件:

修改后的组件代码

import React, { useRef } from 'react';
import emailjs from '@emailjs/browser';
import { useCart } from '../../cart-context';

const EmailOrderForm = () => {
  const { cartItems } = useCart();
  const form = useRef();

  // 格式化订单数据
  const formatOrderDetails = () => {
    return cartItems.map(item => `
      <div style="margin: 8px 0; padding-bottom: 8px; border-bottom: 1px solid #eee;">
        <p><strong>商品:</strong>${item.name}</p>
        <p><strong>价格:</strong>${item.price} Kč</p>
      </div>
    `).join('');
  };

  const sendEmail = (e) => {
    e.preventDefault();
    
    // 从表单获取用户输入,再拼接订单数据
    const formData = new FormData(form.current);
    const templateParams = {
      user_name: formData.get('user_name'),
      user_email: formData.get('user_email'),
      message: formData.get('message'),
      order_details: formatOrderDetails(),
    };

    emailjs
      .send(
        'service_xxxxx',
        'template_xxxxx',
        templateParams,
        'XXxxXXxxXXxxXXxx',
      )
      .then(
        () => console.log('SUCCESS!'),
        () => console.log('FAILED!'),
      );
  };

  return (
    <form ref={form} onSubmit={sendEmail}>
      <label>Name</label>
      <input type="text" name="user_name" />
      <label>Email</label>
      <input type="email" name="user_email" />
      <label>Note</label>
      <textarea name="message" />

      <ul>
        {cartItems.map((item) => (
          <li className="cart-item" key={item.index}>
            <div
              className="cart-item-image"
              style={{
                backgroundImage: `url(${item.image})`,
                width: '100px',
                height: '100px',
                backgroundSize: 'cover',
                backgroundPosition: 'center',
              }}
              alt={item.name}
            ></div>
            <span className="cart-item-name">{item.name}</span>
            <span className="cart-item-price">{item.price}&nbsp;Kč</span>
          </li>
        ))}
      </ul>
      <button className="cart-order" type="submit">
        Order
      </button>
    </form>
  );
};

export default EmailOrderForm;

模板配置和方法1一致

在EmailJS模板中添加{{order_details}}变量,开启HTML渲染即可。

额外提示

  • 如果不需要HTML格式,把formatOrderDetails()改成返回纯文本即可,比如用\n分隔商品信息。
  • 确保你的EmailJS服务ID、模板ID和公钥配置正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:50:24