I'm willing to assume this is just my ignorance on how context works in React, but I'm confused why I am receiving this error
It looks like you are trying to inject Stripe context outside of an Elements context.
Please be sure the component that calls createSource or createToken is within an
<Elements> component.
This is what my code looks like (here's a running example).
class _CardForm extends React.Component {
render () {
return (
<div className="Checkout">
<h1>Available Elements</h1>
<Elements>
<form onSubmit={this.props.stripe.createToken()}>
<label>
Card details
<CardElement />
</label>
<button>Pay</button>
</form>
</Elements>
</div>
)
}
}
const CardForm = injectStripe(_CardForm)
const App = () =>
<StripeProvider apiKey="pk_RXwtgk4Z5VR82S94vtwmam6P8qMXQ">
<CardForm />
</StripeProvider>
ReactDOM.render(<App />, document.querySelector('.App'))
AFAICT, I am definitely trying to "inject Stripe context inside of an Elements context", not outside. I can't see what I'm doing that is breaking the code 馃槙.
Any help would be greatly appreciated!
So I think I figured out why the above code doesn't work.
If you want to use the injectStripe HOC, you cannot do so on a component that renders <Elements> directly. You must pull out the code that <Elements> wraps into it's own component and use injectStripe on that before nesting it within <Elements>.
This example works fine
class _CardForm extends React.Component {
render() {
return (
<form onSubmit={() => this.props.stripe.createToken().then(payload => console.log(payload))}>
<label>
Card details
<CardElement />
</label>
<button>Pay</button>
</form>
)
}
}
const CardForm = injectStripe(_CardForm)
class Checkout extends React.Component {
render() {
return (
<div className="Checkout">
<h1>Available Elements</h1>
<Elements>
<CardForm />
</Elements>
</div>
)
}
}
const App = () => {
return (
<StripeProvider apiKey="pk_RXwtgk4Z5VR82S94vtwmam6P8qMXQ">
<Checkout />
</StripeProvider>
)
}
ReactDOM.render(<App />, document.querySelector('.App'))
Notice that the only difference between this chunk of code and the code in the original issue description is that I've pulled out the wrapping <Elements> code into a new component called <Checkout />.
Unless I am missing something, it would appear that if you want to use injectStripe, you cannot do so on a component that renders <Elements> directly. You must pull out the code that <Elements> wraps into it's own component.
I suppose this makes sense, since the component rendered within <Elements> is injected with the stripe prop at build time, before it actually knows that the code making use of stripe is rendered within <Elements>.
I'd be happy to submit a PR for it if this is something y'all would like more explicit documentation on.
Awesome, I'm glad you figured it out :). That's exactly right. A PR for docs would be great!
@indiesquidge
I've set up my checkout component form using react-stripe-elements' and my onsubmit handler is returning the stripe token. I'm just not sure what I'm supposed to do now?
@rdalfonso once you get the token, you need to send it to your backend, which should call the Stripe API at /v1/charges. You can use one of our server side bindings to help you do this. More instructions in our docs here: https://stripe.com/docs/charges.
@atty-stripe - I came to that same conclusion after re-re-reading the documentation. Thought I could make an API call from the browser. Problem is solved. Thanks!
Most helpful comment
So I think I figured out why the above code doesn't work.
Tl;dr
If you want to use the
injectStripeHOC, you cannot do so on a component that renders<Elements>directly. You must pull out the code that<Elements>wraps into it's own component and useinjectStripeon that before nesting it within<Elements>.Details
This example works fine
Notice that the only difference between this chunk of code and the code in the original issue description is that I've pulled out the wrapping
<Elements>code into a new component called<Checkout />.Unless I am missing something, it would appear that if you want to use
injectStripe, you cannot do so on a component that renders<Elements>directly. You must pull out the code that<Elements>wraps into it's own component.I suppose this makes sense, since the component rendered within
<Elements>is injected with thestripeprop at build time, before it actually knows that the code making use ofstripeis rendered within<Elements>.I'd be happy to submit a PR for it if this is something y'all would like more explicit documentation on.