useEffect is not updating PayPal client id with axios request

95 Views Asked by At

Sometimes it seems the most simpliest stuff is not working. I am doing a GET request to my API to get the paypal_client_id, but it's not updating in time.

import { useState } from 'react';
import axios from 'axios';
import { useEffect } from 'react';

const PayPalButton = ({ total, onPaymentSuccess, onPaymentError, disabled }) => {
  const [paypalClient, setPayPalClient] = useState('test-id');

  useEffect(() => {
    const paypalkey = async () => {
      const { data: clientId } = await axios.get('/api/config/paypal');
      setPayPalClient(clientId);
      console.log(paypalClient);
    };
    paypalkey();
  }, []);
  return (
    <PayPalScriptProvider options={{ 'client-id': paypalClient }}>
      <PayPalButtons
        disabled={disabled}
        forceReRender={[total()]}
        createOrder={(data, actions) => {
          return actions.order.create({
            purchase_units: [
              {
                amount: {
                  value: total(),
                },
              },
            ],
          });
        }}
        onApprove={(data, actions) => {
          return actions.order.capture().then((details) => {
            onPaymentSuccess(data);
          });
        }}
        onError={(err) => {
          onPaymentError();
        }}
      />
    </PayPalScriptProvider>
  );
};

export default PayPalButton;

I thought my useEffect hook would take care to provide the paypal_client_id in time, but it doesn't work.

the API is working, but the request paypal does to authenticate the button is doing it with 'test-id', that proves that my key is not arriving in time.

Any help is much appreciated.

1

There are 1 best solutions below

0
On BEST ANSWER

The useEffect triggers at the first render so it's "normal" that the client-id is not there at the "right time".

You should have a loading in your render to prevent this.

Like :

    const [paypalClient, setPayPalClient] = useState('');
    
        return (
            {!paypalClient ? <p>Loading...</p> : 
(<PayPalScriptProvider options={{ 'client-id': paypalClient }}>
              <PayPalButtons
                disabled={disabled}
                forceReRender={[total()]}
                createOrder={(data, actions) => {
                  return actions.order.create({
                    purchase_units: [
                      {
                        amount: {
                          value: total(),
                        },
                      },
                    ],
                  });
                }}
                onApprove={(data, actions) => {
                  return actions.order.capture().then((details) => {
                    onPaymentSuccess(data);
                  });
                }}
                onError={(err) => {
                  onPaymentError();
                }}
              />
            </PayPalScriptProvider>)}
          );

Or you can simply store your client-id in your environment variables