从POST请求获取响应数据后反应JS&Axios Render

时间:2019-11-23 19:31:39

标签: javascript node.js reactjs axios stripe-payments

在axios POST请求后如何呈现组件?在收到Stripe的成功响应后,我想加载一个新组件。我试图通过在收到响应后添加setState来更新组件的状态,如果状态具有任何值,则加载一个简单的div。我遇到的问题是,当我使用setState时,该组件未重新渲染。

下面是我如何配置条带组件和Express服务器:

import StripeCheckout from 'react-stripe-checkout';
import axios from 'axios';
import './stripe-button.styles.scss';
import { createStructuredSelector } from 'reselect';
import { selectCurrentUser } from '../../redux/user/user.selectors';
import { setCurrentUser } from '../../redux/user/user.actions';
class StripeCheckoutButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cardListBacklog: []
    };
  }

  onToken = token => {
    console.log(token);
    const { cartItems, price } = this.props;
    const priceForStripe = price * 100;
    const orderSummary = cartItems.reduce(
      (cartItemAll, cartItem) =>
        (cartItemAll += cartItem.name + cartItem.quantity),
      ''
    );
    axios({
      url: 'payment',
      method: 'post',
      data: {
        amount: priceForStripe,
        order: orderSummary,
        token
      }
    })
    .then(response => {
      alert(
        `Payment successful, ${response.data.success.billing_details.name}; please check your email for your receipt.`
      );
      this.setState({cardListBacklog: response.data});
    })
    .catch(error => {
      console.log('Payment error: ', JSON.parse(error));
      alert('There was an issue with your payment. Please try again!');
    });
  };
  render() {
    const publishableKey = 'pk_test_gxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    const { price } = this.props;
    const priceForStripe = price * 100;
    return (
      this.state.cardListBacklog.length
        ? 
        <div>Payment Successful</div>
       :
      <StripeCheckout
        label="Pay Now"
        name="Ltd."
        billingAddress
        shippingAddress
        image="https://i.imgur.com/vWgUzv.png"
        description={`Your total is $${price} USD`}
        amount={priceForStripe}
        panelLabel="Pay Now"
        token={this.onToken}
        stripeKey={publishableKey}
        label="Pay with ?"
      />
    );
  }
}


export default StripeCheckoutButton;


这是我的Server.js:


  const express = require('express');
  const cors = require('cors');
  const bodyParser = require('body-parser');
  const path = require('path');

  if (process.env.NODE_ENV !== 'production') require('dotenv').config();

  const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

  const app = express();
  const port = process.env.PORT || 5000;

  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: true }));

  app.use(cors());

  if (process.env.NODE_ENV === 'production') {
    app.use(express.static(path.join(__dirname, 'client/build')));
    app.get('*', function(req, res) {
      res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
    });
  }

  app.listen(port, error => {
    if (error) throw error;
    console.log('Server running on port: ' + port);
  });

  app.post('/payment', (req, res) => {
    const body = {
      source: req.body.token.id,
      amount: req.body.amount,
      receipt_email: req.body.token.email,
      description: req.body.order,
      currency: 'usd'
    };

    stripe.charges.create(body, (stripeErr, stripeRes) => {
      if (stripeErr) {
        res.status(500).send({ error: stripeErr });
      } else {
        res.status(200).send({ success: stripeRes });
      }
    });

  });

2 个答案:

答案 0 :(得分:2)

this.state.cardListBacklog.length

这是问题。它在更新前给0,在更新后给undefined。控制台日志,并检查其是否为真。

this.state = {
  cardListBacklog: false
};

  this.setState({cardListBacklog: true});

应该可以解决问题。

答案 1 :(得分:0)

我想,您希望stripeRes处于该状态,但是您正在接收一个对象 改为{success: stripeRes}

您在此处使用服务器中的对象作为响应

res.status(200).send({ success: stripeRes });

但是在客户端state中,您期望数组而不是对象。

this.state.cardListBacklog.length

默认情况下,对象没有length属性。 您应该检查客户端上的其他内容。也许你应该更新状态 像

这样的成功响应
this.setState({cardListBacklog: response.data.success });

这不是很酷,但是应该让您知道客户端和服务器端期望的是不同的东西。

您应该重新考虑您的API。

如果您不希望在不久的将来使用响应数据,则在此处使用成功响应标志(https://stackoverflow.com/a/59011695/10559239)的想法对您来说很有意义。第一步很好。 但是,我看到的主要问题是服务器和客户端之间的不一致。