简体   繁体   English

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

[英]React JS & Axios Render after getting response data from POST request

How would I go about rendering a component after an axios POST request?在 axios POST 请求之后我将如何渲染组件? I want to load a new component after the success response has been received from Stripe.我想在收到来自 Stripe 的成功响应后加载一个新组件。 I am trying to update the state of my component by adding a setState after receiving the response and load a simple div if the state has any values.我试图通过在收到响应后添加一个 setState 来更新我的组件的状态,如果状态有任何值,则加载一个简单的 div。 The issue I am having is that component is not re-rendering when I use the setState.我遇到的问题是当我使用 setState 时组件没有重新渲染。

Below is how I have a stripe component setup and the express server:下面是我如何设置条带组件和快速服务器:

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;


Here is my Server.js:这是我的 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 });
      }
    });

  });

this.state.cardListBacklog.length

This is the issue.这是问题。 Its giving 0 before update, and undefined after its updated.它在更新前给出 0,更新后给出未定义。 Console log and check if its true.控制台日志并检查其是否属实。

this.state = {
  cardListBacklog: false
};

and

  this.setState({cardListBacklog: true});

should do the trick.应该做的伎俩。

I guess, you expects stripeRes in the state, but you are receiving an object {success: stripeRes} instead.我想,您希望在状态中使用stripeRes ,但您收到的是一个对象{success: stripeRes}

You response with an object from the server here您在此处使用来自服务器的对象进行响应

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

But on the client side in the state you expect the array, not an object.但是在客户端的state您期望的是数组,而不是对象。

this.state.cardListBacklog.length

Object doesn't have length property by default.对象默认没有length属性。 You should check something else on the client.您应该检查客户端上的其他内容。 Maybe you should update state on success response like也许您应该更新成功响应的状态,例如

this.setState({cardListBacklog: response.data.success });

This is not super cool, but should give you an idea that client side and server side expect different things.这不是很酷,但应该让您知道客户端和服务器端期望不同的东西。

You should rethink your API.您应该重新考虑您的 API。

The idea to use flag of successful response here ( https://stackoverflow.com/a/59011695/10559239 ) makes sense to you, if you doesn't want to use response data in near future.如果您不想在不久的将来使用响应数据,那么在此处使用成功响应标志 ( https://stackoverflow.com/a/59011695/10559239 ) 的想法对您很有意义。 Good as a first step.作为第一步很好。 But the main problem, as I can see is inconsistency between server and client.但我所看到的主要问题是服务器和客户端之间的不一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM