Reputation: 167
I'm implementing the PayPal Smart Payment Buttons with React, and every time my component re-renders I receive a duplicate of the buttons (with the one on the bottom holding the correct transaction information).
Clearly I need to close the buttons, if I try so I receive the error that window.paypal.close()
is not a function.
I tried to follow this example: Paypal React shows extra buttons after changing amount
Here is my code, I'm using Redux for state management and I need to rerender the component if items in the shopping cart are removed (to update the item information of the transaction):
useEffect(() => {
if (window.myButton) {
window.myButton.close()
}
window.myButton = window.paypal
.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
{
description: "test transaction",
amount: {
currency_code: "USD",
value: document.getElementById("totalAmount").innerHTML,
breakdown: {
item_total: {
currency_code: "USD",
value: document.getElementById("totalAmount").innerHTML
}
}
}
,
items: itemsInCart.map(item => {
console.log(item.value)
return {
name: item.name,
unit_amount: {
currency_code: "USD",
value: String(item.price)
},
quantity: "1"
}
})
}
]
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
}
.catch(function(error) {
console.error("Error writing document: ", error);
});
},
onError: err => {
// setError(err);
console.error(err);
}
})
.render(paypalRef.current)
}, [itemsInCart]);
Upvotes: 1
Views: 1632
Reputation: 30377
})
.render(paypalRef.current)
The problem is you are setting myButton to the .render() promise result, not the Button itself.
You need to store a reference to the actual Button (before rendereing it), and only then .render() it -- so that later you can call .close() on the reference. Basically:
let myButton = paypal.Buttons(
....
});
myButton.render(paypalRef.current)
// and at some later point in time...
myButton.close();
Upvotes: 5