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
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.