Shei
Shei

Reputation: 483

PayPal React shows extra buttons after changing amount

WITHOUT react-paypal-button-v2 ~~~has an ovehead of 60KB

Similar question here but they suggest react-paypal-button-v2

I'm Trying to make a React PayPal button that changes the billing amount on props change.

I call the following component with props price and every time the price change i would like to re-render the button to update the actual price. WITHOUT react-paypal-button-v2

const PaypalForm = props => {
  let paypalRef = useRef();

  useEffect(() => {      
    window.paypal
      .Buttons({
        createOrder: (data, actions) => {
          return actions.order.create({
            purchase_units: [
              {
                description: "test",
                amount: {
                  currency_code: "USD",
                  value: props.price
                }
              }
            ]
          });
        },
        onApprove: async (data, actions) => {
          const order = await actions.order.capture();
          console.log(order);
        },
        onError: err => {
          setError(err);
          console.error(err);
        }
      })
      .render(paypalRef.current);
  }, [props.price]);

  return (
    <Row className="justify-content-center">
      {error && <div>Uh oh, an error occurred! {error.message}</div>}
      <div ref={paypalRef} />
    </Row>
  );
};

Everything is working except that a new button is created and added in the bottom of old one at each props change. I would like my new button to replace the old one. Without using react-paypal-button-v2

Upvotes: 2

Views: 1284

Answers (1)

Preston PHX
Preston PHX

Reputation: 30377

Something like:

useEffect(() => {
    if(window.myButton) window.myButton.close();
    window.myButton = window.paypal
      .Buttons({
        createOrder: (data, actions) => {
          return actions.order.create({
            purchase_units: [
              {
                description: "test",
                amount: {
                  currency_code: "USD",
                  value: props.price
                }
              }
            ]
          });
        },
        onApprove: async (data, actions) => {
          const order = await actions.order.capture();
          console.log(order);
        },
        onError: err => {
          setError(err);
          console.error(err);
        }
      });
    window.myButton.render(paypalRef.current);

However, you do not actually need to re-render the button on price change!

You can do value: document.getElementById('...').value or similar (or whatever variable or function call you need)

In your example, if props.price returns the (new/current) desired value when the button is clicked, then that value will be used.

Basically, the createOrder function isn't called until you click a button.

Upvotes: 5

Related Questions