首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将动态金额传递给Paypal React Button而不进行重呈现

如何将动态金额传递给Paypal React Button而不进行重呈现
EN

Stack Overflow用户
提问于 2021-09-20 19:34:53
回答 1查看 696关注 0票数 0

我使用的是react-paypal-js,需要在单击PayPal按钮时设置一个动态数量。

问题:createOrder函数不能从我的状态获取数据(可能是因为它在PayPal脚本上下文下)。

不工作的示例:

代码语言:javascript
复制
    const [amount, setAmount] = useState('');

    const handleCreatePaypal = (data, actions) => {
        const orderAmount = parseFloat(amount).toFixed(2) || '1.00'; //amount is the state
        console.log(amount, orderAmount)
        return actions.order.create({
            purchase_units: [
                { amount: { value: orderAmount } }
            ]
        })
    }

    return (
        <PayPalScriptProvider options={paypalOptions}>
            <PayPalButtons
                createOrder={(data, actions) => handleCreatePaypal(data, actions)}
                onApprove={(data, actions) => handlePaypalApprove(data, actions)}
                onError={handlePaymentError}
            />
        </PayPalScriptProvider>
    )

不完美解决方案:

  1. HTML中获取金额,但我并不真的想这么做。
代码语言:javascript
复制
    const amountRef = useRef(null);  //ref on input not showing here
    ...
    const orderAmount = parseFloat(amountRef.current.value).toFixed(2) || '1.00'; //get value from html
    ...
  1. 当数量变化时,强制重呈现。但这将导致按钮消失,并再次显示时,金额的变化。
代码语言:javascript
复制
        <PayPalScriptProvider options={paypalOptions}>
            <PayPalButtons
                createOrder={(data, actions) => handleCreatePaypal(data, actions)}
                forceReRender={[amount]}  //force re-render when amount changes
            />
        </PayPalScriptProvider>

有解决这个问题的办法吗?提前感谢!

如果没有解决方案,我可能需要从后端进行集成:

我不想这太复杂,因为它只是一个简单的捐赠按钮。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-21 08:33:03

从后端集成通常是最健壮的解决方案,尤其是对于电子商务--但由于这是一个简单的捐赠用例,我可以看到您可能希望避免这种情况。

有各种可能的解决方案,包括使用其他状态框架(如Redux ),但您似乎要做的是在按钮之上的父组件级别管理状态,以及bind its createOrder ("handleCreatePayPal")方法等,以便this处于上下文中,并且它们可以访问其状态。

下面是一个可运行的代码框示例 (基于使用重呈现的文档示例。,但这里没有完成)

代码语言:javascript
复制
import { PayPalScriptProvider, PayPalButtons } from "@paypal/react-paypal-js";
import * as React from "react";

const debug = true;

const initialState = {
  amount: "2.00",
  orderID: "",
  onApproveMessage: "",
  onErrorMessage: ""
};

export default class App extends React.Component<{}, typeof initialState> {
  constructor(props: any) {
    super(props);
    this.state = initialState;

    this.onChange = this.onChange.bind(this);
    this.createOrder = this.createOrder.bind(this);
    this.onApprove = this.onApprove.bind(this);
    this.onError = this.onError.bind(this);
    this.onClick = this.onClick.bind(this);
  }

  onChange(event: React.ChangeEvent<HTMLSelectElement>) {
    this.setState({
      amount: event.target.value,
      orderID: "",
      onApproveMessage: "",
      onErrorMessage: ""
    });
  }

  createOrder(data: Record<string, unknown>, actions: any) {
    if (debug) console.log("Creating order for amount", this.state.amount);
    return actions.order
      .create({
        purchase_units: [
          {
            amount: {
              value: this.state.amount
            }
          }
        ]
      })
      .then((orderID: any) => {
        this.setState({ orderID: orderID });
        return orderID;
      });
  }

  onApprove(data: any, actions: any) {
    let app = this;
    return actions.order.capture().then(function (details: any) {
      app.setState({
        onApproveMessage: `Transaction completed by ${details.payer.name.given_name}!`
      });
    });
  }

  onError(err: Record<string, unknown>) {
    this.setState({
      onErrorMessage: err.toString()
    });
  }

  onClick() {
    if (debug) console.log("When clicked, amount was", this.state.amount);
  }

  render() {
    return (
      <div style={{ minHeight: "300px" }}>
        <table className="table" style={{ maxWidth: "400px" }}>
          <tbody>
            <tr>
              <th>
                <label htmlFor="amount">Order Amount: </label>
              </th>
              <td>
                <select onChange={this.onChange} name="amount" id="amount">
                  <option value="2.00">$2.00</option>
                  <option value="4.00">$4.00</option>
                  <option value="6.00">$6.00</option>
                </select>
              </td>
            </tr>
            <tr>
              <th>Order ID:</th>
              <td>{this.state.orderID ? this.state.orderID : "unknown"}</td>
            </tr>
            <tr>
              <th>On Approve Message: </th>
              <td data-testid="message">{this.state.onApproveMessage}</td>
            </tr>
            <tr>
              <th>On Error Message: </th>
              <td data-testid="error">{this.state.onErrorMessage}</td>
            </tr>
          </tbody>
        </table>
        <PayPalScriptProvider options={{ "client-id": "test" }}>
          <PayPalButtons
            createOrder={this.createOrder}
            onApprove={this.onApprove}
            onError={this.onError}
            onClick={this.onClick}
          />
        </PayPalScriptProvider>
      </div>
    );
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69259922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档