如何在React组件中正确使用Yandex.Metrika电商层
在React组件中向Yandex.Metrika电商层发送数据的正确方式
你已经在index.html中完成了Yandex.Metrika的基础配置,并指定了电商数据通过dataLayer传递。下面是在React组件中发送电商数据的几种实用方案:
1. 直接在组件中使用window.dataLayer
由于dataLayer挂载在全局window对象上,你可以在组件的事件处理函数或生命周期钩子中直接调用它,注意先判断对象存在性避免报错:
函数组件示例(产品详情页+添加购物车)
import { useEffect } from 'react'; const ProductCard = ({ product }) => { // 组件挂载时发送产品详情浏览数据 useEffect(() => { if (typeof window !== 'undefined' && window.dataLayer) { window.dataLayer.push({ ecommerce: { detail: { products: [ { id: product.id, name: product.name, price: product.price, category: product.category } ] } } }); // 按Metrika规范,发送后重置电商对象避免重复触发 window.dataLayer.push({ ecommerce: null }); } }, [product]); // 点击加入购物车时发送数据 const handleAddToCart = () => { // 先执行业务逻辑(比如更新购物车状态) // ... if (typeof window !== 'undefined' && window.dataLayer) { window.dataLayer.push({ ecommerce: { add: { products: [ { id: product.id, name: product.name, price: product.price, quantity: 1 } ] } } }); window.dataLayer.push({ ecommerce: null }); } }; return ( <div className="product-card"> <h3>{product.name}</h3> <p>${product.price}</p> <button onClick={handleAddToCart}>加入购物车</button> </div> ); }; export default ProductCard;
类组件示例(结账完成事件)
import React, { Component } from 'react'; class CheckoutPage extends Component { handleOrderComplete = () => { // 执行业务逻辑(比如提交订单、跳转成功页) // ... if (typeof window !== 'undefined' && window.dataLayer) { window.dataLayer.push({ ecommerce: { purchase: { actionField: { id: this.props.orderId, revenue: this.props.total, tax: this.props.tax, shipping: this.props.shipping }, products: this.props.cartItems.map(item => ({ id: item.id, name: item.name, price: item.price, quantity: item.quantity })) } } }); window.dataLayer.push({ ecommerce: null }); } }; render() { return ( <div className="checkout-page"> <h2>确认订单</h2> {/* 结账表单内容 */} <button onClick={this.handleOrderComplete}>完成支付</button> </div> ); } } export default CheckoutPage;
2. 封装工具函数(推荐)
为了避免重复代码,你可以封装一个全局工具函数来统一处理电商数据发送:
新建工具文件utils/metrika.js
export const sendEcommerceEvent = (eventData) => { // 兼容服务端渲染场景(比如Next.js) if (typeof window === 'undefined' || !window.dataLayer) return; window.dataLayer.push({ ecommerce: eventData }); window.dataLayer.push({ ecommerce: null }); };
在组件中导入使用
import { sendEcommerceEvent } from '../utils/metrika'; const CartItem = ({ item, updateQuantity }) => { const handleQuantityChange = (newQty) => { updateQuantity(item.id, newQty); sendEcommerceEvent({ update: { products: [ { id: item.id, name: item.name, price: item.price, quantity: newQty } ] } }); }; return ( <div className="cart-item"> <span>{item.name}</span> <input type="number" value={item.quantity} onChange={(e) => handleQuantityChange(parseInt(e.target.value))} /> </div> ); };
关键注意事项
- 兼容服务端渲染:必须判断
typeof window !== 'undefined',避免在SSR环境下出现window is undefined的报错。 - 遵循Metrika数据格式:发送的电商数据字段(如
add、purchase、products下的属性)要符合Yandex.Metrika的官方规范,否则数据无法被正确统计。 - 重置电商对象:每次发送数据后推送
{ ecommerce: null }是Metrika推荐的做法,可防止后续页面交互重复触发同一事件。
内容的提问来源于stack exchange,提问作者Mike strn
相关产品推荐
相关产品推荐

