[英]PayPal Smart Payment Buttons using old State
所以场景是我有一个 React + Redux 电子商务商店,并且有一个结帐页面,其中列出了购物车中的所有物品。 这很好用,每次我添加产品时按钮都会重新呈现,但是,可以选择从结帐页面上的购物车中删除项目,尽管实际的 state 发生了变化,但 Paypal 按钮使用旧的 Z9ED39E2EA931586B6A93158A(假设因为按钮不会重新渲染)。 我已经将按钮包装在 useEffect function 中,每当购物车中的物品发生 state 更改时都应该运行该按钮,但是,事实并非如此,我只是不知道为什么。
这是代码:
import {useSelector, useDispatch} from 'react-redux'
import {removeProduct} from '../redux/cart/cart.actions'
import './Cart.scss'
import CartItem from '../components/cartComponent/cartItem'
const mapState = ({ cart }) => ({
itemsInCart: cart.itemsInCart,
total: cart.total
})
const Cart = props => {
const [paidFor, setPaidFor] = useState(false);
const dispatch = useDispatch();
const {itemsInCart} = useSelector(mapState);
const {total} = useSelector(mapState);
let paypalRef = useRef();
const clickHandler = (e) => {
e.preventDefault();
const removeIndex = itemsInCart.findIndex(item => {
return item.id === e.target.id
})
dispatch(removeProduct(removeIndex,itemsInCart[removeIndex]))
}
useEffect(() => {
window.paypal
.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
{
description: "product.description",
amount: {
currency_code: 'USD',
value: total,
},
},
],
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
setPaidFor(true);
console.log(order);
},
onError: err => {
setError(err);
console.error(err);
},
})
.render(paypalRef.current);
},[itemsInCart]);
return (
<>
{paidFor ? (
<div><h1>Congrats you just bought an Article</h1></div>
):
<>
<h1>Your Shopping Cart</h1>
<div className = "main">
<form className="cart-area">
<ul className="cart-ui">
{itemsInCart.map((item, index)=> {
return <CartItem
clicked={clickHandler}
name={item.name}
price={item.price}
id={item.id}
key={index}
/>
})}
</ul>
<div className="cart-summary">
<div className ="cart-wrapper">
<div className="name-price-wrapper">
<p className="name">Items</p>
<p className="price">{total}€</p>
</div>
<div ref={paypalRef}></div>
</div>
</div>
</form>
</div>
</>
}
</>
)
}
export default Cart;
当我将 useEffect 钩子更改为总是重新渲染时,我多次获得按钮(取决于我删除了多少项目),并且当单击底部的按钮时,它实际上以正确的数量工作。 所以我必须关闭以前的按钮,因为它们会被渲染。
关注@Preston PHX 的引用帖子时,我的代码如下所示:
useEffect(() => {
if(window.myButton) window.paypal.close();
window.myButton = window.paypal
.Buttons({
createOrder: (data, actions) => {
console.log(total)
return actions.order.create({
purchase_units: [
{
description: "product.description",
amount: {
currency_code: 'USD',
value: total,
},
},
],
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
setPaidFor(true);
console.log(order);
},
onError: err => {
setError(err);
console.error(err);
},
})
.render(paypalRef.current)
});
在这里我得到错误window.myButton.close() is not a function
...?
你误解了useEffect的参数: https://reactjs.org/docs/hooks-effect.html
仅当该参数更改时才会导致效果运行
每当该参数更改时,它都不会导致效果运行
另一个可能的问题是关闭现有按钮,如果您真的要重新渲染它们。 如果您的 purchase_units object 引用了在单击按钮时评估的动态变量/函数,则不需要重新渲染它们。 但是,如果您要重新呈现按钮,则可能需要关闭现有按钮。 您可以通过在调用.render 之前存储对 window.PayPal.Buttons(...) 的引用来执行此操作,以便在第二次调用.render 之前可以 then.close() (如果已定义)。
如何做到这一点的答案: https://stackoverflow.com/a/62349799/2069605
import React from "react";
import ReactDOM from "react-dom"
const PayPalButton = paypal.Buttons.driver("react", { React, ReactDOM });
function YourComponent({price}) {
const createOrder = (data, actions) =>{
return actions.order.create({
purchase_units: [
{
amount: {
value: `${price}`,
},
},
],
});
};
const onApprove = (data, actions) => {
return actions.order.capture();
};
return (
<PayPalButton
createOrder={(data, actions) => createOrder(data, actions)}
onApprove={(data, actions) => onApprove(data, actions)}
/>
);
}
或尝试使用 useRef 挂钩
import React, { useRef, useEffect } from 'react';
const Paypal = ({ amount }) => {
const paypal = useRef();
useEffect(() => {
if (window.paypalBtn) window.paypalBtn.close();
window.paypalBtn = window.paypal.Buttons({
createOrder: function (data, actions) {
// This function sets up the details of the transaction, including the amount and line item details.
return actions.order.create({
purchase_units: [
{
amount: {
value: `${amount}`,
},
},
],
});
},
onApprove: function (data, actions) {
// This function captures the funds from the transaction.
return actions.order.capture().then(function (details) {
// This function shows a transaction success message to your buyer.
console.log('details', details);
alert('Transaction completed by ' + details.payer.name.given_name);
});
},
onError: function (err) {
console.error(err);
},
});
window.paypalBtn.render(paypal.current);
}, [amount]);
return (
<div>
<div ref={paypal}></div>
</div>
);
};
export default Paypal;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.