简体   繁体   中英

Stripe Payment Form not Displaying in React

I am building a React application for a project and I am trying to incorporate Stripe into it in order to accept payments for the balance on a user's account. When I click the button and display the url for the payment component, the payment component is not displayed. I suspect it has something to do with my routing. App code as follows:

    import React, { Component } from 'react';
    import { Switch, Route, Redirect, withRouter } from "react-router-dom";
    //import { loadStripe } from "@stripe/stripe-js";
    import { connect } from 'react-redux'
    import { loggedIn } from "./actions/currentAccount.js"
    import { Elements, StripeProvider } from "react-stripe-elements";
    import PaymentNew from './components/PaymentNew'
    import AccountContainer from './containers/AccountContainer'
    import Navbar from './components/Navbar'
    import DepartmentsContainer from './containers/DepartmentsContainer'
    import Login from './components/registrations/Login'
    import Signup from './components/registrations/Signup'


    class App extends Component {

      componentDidMount() {
        if (localStorage.getItem("loggedIn")) {
          loggedIn(this.props.history);
        }
      }

      render() {

            //const stripe = loadStripe('pk_test_tZpOKpVsO8ccsjSLbrnuwwEH');
            const currentAccount = localStorage.getItem("loggedIn");
            console.log('current account is: ' + JSON.stringify(this.props.loginFormReducer));
    
        return (
          <div className="App">
                <h2>{ currentAccount ? 
            `Logged in as ${this.props.loginFormReducer.attributes.name}` :
            "Not logged in" }</h2> 
            <Switch>   
              <Route exact path='/api/v1/login' render={props => ( <Login {...props}/>)}/>
              <Route exact path='/api/v1/signup' render={props => ( <Signup {...props}/>)}/>
              <Redirect from="/logout" to="api/v1/login" />
              <Route exact path='/accounts/:id' render={props => {
                return <AccountContainer {...props} account={currentAccount}/>
              } }/>
              <Route exact path='/accounts/:id/departments' render={props => {
                return <DepartmentsContainer/>
              } }/>
              <Route path='/accounts/:id/payments/new' render={props => {
                <StripeProvider apiKey="pk_test_tZpOKpVsO8ccsjSLbrnuwwEH">
                  <Elements>
                    <PaymentNew {...props}/>
                  </Elements>
                </StripeProvider>
              }} />
            </Switch>
             { currentAccount ? <Navbar account={currentAccount}/> : null } 
        </div>
        );
      }
    }

    const mapStateToProps = state => { //what portion of state to provide to props 
      return { //executed with each change to the store. 
        ...state
      };
    }

    export default withRouter(connect(mapStateToProps, { loggedIn })(App)); // specifies 
    component to provide data to. ```

Routing is as follows:
Routes.rb
Rails.application.routes.draw do

#root 'api/v1/login'
post 'api/v1/login',    to: 'api/v1/sessions#create'
delete 'api/v1/logout',   to: 'api/v1/sessions#destroy'
post 'api/v1/signup' => 'api/v1/accounts#create'
get 'api/v1/logged_in' => 'api/v1/sessions#is_logged_in?'

 namespace :api do
    namespace :v1 do 
    resources :accounts do 
        resources :departments 
        resources :payments
    end
  end
 end

end

For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html


The Payment form:
import React from 'react'
import { useState } from 'react';
import { withRouter } from "react-router-dom";
import { connect } from "react-redux";
import {injectStripe} from 'react-stripe-elements';
import { newPayment } from "../actions/currentPayments";


const PaymentNew = (props) => {

  const [form, setForm] = useState({
    amount: ''
  });

  console.log(this.props)

  //const accountId = this.props

  const handlePaymentFormChange = (event, target) => {
     setForm({
      ...form,
     [target]: event.target.value, 
    });
  }


  const handlePaymentFormSubmit = (event, accountId) => {
       event.preventDefault()
       newPayment(form, accountId)
  }

  return (
       <div className="NewPayment">
        <h1>New Payment</h1>
        <form onSubmit={handlePaymentFormSubmit}>
          <input
            placeholder="amount"
            type="text"
            name="amount"
            autoComplete="on"
            value={form.amount}
            onChange={(event)=> handlePaymentFormChange(event, "amount")}
          /><br/>
          <input
            placeholder="cardnumber"
            type="text"
            name="card number"
            autoComplete="on"
            value={form.cardnumber}
            onChange={(event)=> handlePaymentFormChange(event, "cardnumber")}
           /><br/>
          <input
            placeholder="expiration"
            type="text"
            name="expiration"
            autoComplete="on"
            value={form.expiry}
            onChange={(event)=> handlePaymentFormChange(event, "expiration")}
          /><br/>
          <input
            placeholder="cvc"
            type="text"
            name="cvc"
            autoComplete="on"
            value={form.cvc}
            onChange={(event)=> handlePaymentFormChange(event, "cvc")}
          /><br/>
        <button placeholder="submit" type="submit">
            Make Payment
           </button> 
          <br></br>     
          <br></br>             
          <div>
          </div>
          </form>
          <div>
        </div>
      </div>
  )
}

/*function InjectedCheckoutForm() {
  return (
    <ElementsConsumer>
      {({ stripe, elements }) => (
        <CheckoutForm stripe={stripe} elements={elements} />
      )}
    </ElementsConsumer>
  );
}*/

const mapStateToProps = state => {
   return {
     form: state.form 
  };
};

export default withRouter(connect(mapStateToProps, { newPayment } ), 
injectStripe(PaymentNew));

I have tried to change the route in app from exact path to just path. I have also removed elements and StripeProvider. In both cases the component still does not display and all that I see is the navbar. Any help and suggestions are appreciated. 

You're going to need to break this down layer by layer and determine what is causing the React component to not be rendered. It's not clear which components are "missing" for you. Can you add screenshots showing missing content?

One thing you might try is moving the <StripeProvider> outside of the router <Switch> so that it is persistent.

Simplify your component tree. Find out where it fails.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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