簡體   English   中英

PayPal 使用舊 State 的智能支付按鈕

[英]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)}
    />
  );
}

單擊此處獲取 Paypal 文檔

或嘗試使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM