React父子组件通信:ProductModal点击按钮触发父组件函数
我来帮你实现这个产品列表+弹窗通知的功能,下面是基于React的完整代码示例,你可以根据自己的技术栈调整细节:
整体实现思路
app.js负责从API拉取产品数据、渲染产品列表,同时管理模态框的显示状态,以及定义产品更新的核心函数ProductModal.js作为弹窗组件,接收产品信息并渲染UI,处理“无货通知”按钮的点击逻辑:先触发邮件发送,再调用产品更新函数
1. app.js 代码实现
import React, { useState, useEffect } from 'react'; import ProductModal from './ProductModal'; function App() { const [products, setProducts] = useState([]); const [selectedProduct, setSelectedProduct] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); // 从API获取产品列表 useEffect(() => { const fetchProducts = async () => { try { const response = await fetch('你的产品API接口地址'); const productData = await response.json(); setProducts(productData); } catch (err) { console.error('加载产品列表失败:', err); } }; fetchProducts(); }, []); // 打开产品详情弹窗 const openProductModal = (product) => { setSelectedProduct(product); setIsModalOpen(true); }; // 关闭弹窗 const closeProductModal = () => { setIsModalOpen(false); setSelectedProduct(null); }; // 更新产品列表的核心函数 const getUpdatedProduct = async () => { try { // 这里可以重新拉取最新产品数据,或者针对性更新指定产品 const response = await fetch('你的产品API接口地址'); const updatedProducts = await response.json(); setProducts(updatedProducts); console.log('产品列表已同步最新状态'); } catch (err) { console.error('更新产品数据失败:', err); } }; return ( <div className="app-container"> <h1>产品展示</h1> <div className="product-grid"> {products.map(product => ( <div key={product.id} className="product-card"> <img src={product.smallImageUrl} alt={product.title} onClick={() => openProductModal(product)} style={{ cursor: 'pointer' }} /> <p className="product-title">{product.title}</p> </div> ))} </div> {/* 条件渲染弹窗组件 */} {isModalOpen && selectedProduct && ( <ProductModal product={selectedProduct} onClose={closeProductModal} triggerProductUpdate={getUpdatedProduct} /> )} </div> ); } export default App;
2. ProductModal.js 组件实现
import React from 'react'; const ProductModal = ({ product, onClose, triggerProductUpdate }) => { // 发送无货通知邮件的函数 const sendOutStockNotification = async () => { try { // 调用后端接口发送邮件(前端直接发邮件易被拦截,推荐后端处理) await fetch('你的邮件发送API接口地址', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ productId: product.id, productName: product.title, // 可添加收件人、用户联系方式等额外参数 }), }); alert('邮件已发送,我们会尽快补货!'); } catch (err) { console.error('发送通知邮件失败:', err); alert('发送邮件失败,请稍后重试'); } }; // 按钮点击事件:先发邮件,再触发产品更新 const handleOutStockClick = async () => { await sendOutStockNotification(); triggerProductUpdate(); onClose(); // 点击后自动关闭弹窗 }; return ( <div className="modal-overlay" onClick={onClose}> <div className="modal-body" onClick={(e) => e.stopPropagation()}> <button className="modal-close-btn" onClick={onClose}>×</button> <img src={product.largeImageUrl} alt={product.title} className="modal-product-image" /> <h2 className="modal-product-title">{product.title}</h2> <button className="out-of-stock-btn" onClick={handleOutStockClick} > Product niet aanwezig </button> </div> </div> ); }; export default ProductModal;
3. 关键细节说明
- 模态框交互:通过
isModalOpen状态控制弹窗显示/隐藏,点击遮罩层或关闭按钮可关闭弹窗,点击弹窗内部不会触发关闭(通过stopPropagation阻止事件冒泡) - 邮件发送逻辑:建议通过后端API处理邮件发送,避免前端直接暴露邮箱配置导致安全问题
- 产品更新时机:等待邮件发送完成后再调用
getUpdatedProduct,确保通知动作完成后再同步最新产品状态 - 样式补充:需要自行添加CSS样式美化产品列表和弹窗,比如给
.modal-overlay添加半透明背景,.modal-body设置居中布局等
内容的提问来源于stack exchange,提问作者valheru
相关产品推荐
相关产品推荐

