React 问题:传入PayPal沙箱组件的props未随购物车更新如何解决
问题根因
- PayPal按钮组件的初始化
useEffect依赖数组为空,仅会在组件首次挂载时执行1次,后续prixTotal、paniers两个props更新时,不会触发PayPal按钮的重新初始化,按钮内部始终保留首次渲染时的旧参数值。 - 未做旧PayPal按钮实例的销毁逻辑,直接重新渲染会出现多个按钮重复叠加的问题。
修复方案
修改PayPal组件的useEffect逻辑:
- 给
useEffect添加prixTotal、paniers作为依赖项,props变化时自动重新初始化按钮 - 新增清理函数销毁旧的PayPal按钮实例,避免重复渲染
修改后的PayPal组件代码如下:
export default function Paypal({prixTotal, paniers}) { const PDFGeneration = () => { var doc = new jsPDF('p','px','a4','false'); var lesPaniers = paniers.map(panier => [panier.PRO_NOM, panier.PAN_QUANTITE, panier.PRO_PRIX ]); doc.text(10,15,'Résumé de votre commande : '); doc.autoTable({ theme: 'grid', startY: 20, head: [['Nom', 'Quantité', 'Prix (€)']], body: lesPaniers, }); doc.text(10,120,`Total de la commande : ${prixTotal} €`); doc.text(10,150,'A la prochaine fois !'); doc.save('CommandeInfo.pdf'); } const paypal = useRef() useEffect(() => { // 存储PayPal按钮实例用于后续清理 const payPalButtonsInstance = window.paypal.Buttons({ style: { color: 'gold', }, createOrder: (data, actions) => { return actions.order.create({ intent: 'CAPTURE', purchase_units: [ { description: 'Transaction du site E-Commerce.', amount: { currency_code: 'EUR', value: prixTotal } }] }) }, onApprove: (data, actions) => { createCommande(true).then(response => { PDFGeneration(); window.location.reload(false); }); return actions.order.capture(); }, onCancel: (data, actions) => { console.log("Transaction annulé"); console.log(prixTotal) } }) payPalButtonsInstance.render(paypal.current) // 清理函数:组件卸载/依赖变化时销毁旧按钮 return () => { if (payPalButtonsInstance) { payPalButtonsInstance.close(); } // 清空容器避免残留内容 if (paypal.current) { paypal.current.innerHTML = ''; } } // 新增依赖项,props变化时触发按钮重渲染 }, [prixTotal, paniers]) return ( <div> <div ref={paypal}></div> </div> ); }
如果修改后仍有偶发不更新的情况,可以在父组件调用PayPal时添加动态key,强制组件在总价/购物车内容变化时销毁重建:
{(total.length > 0 && paniers.length > 0) && <PayPal key={`${total[0].TOTAL}-${paniers.length}`} prixTotal={total[0].TOTAL} paniers={paniers} />}
内容的提问来源于stack exchange,提问作者Quentin
相关产品推荐
相关产品推荐

