Skip to content
This repository has been archived by the owner on Mar 27, 2021. It is now read-only.

Getting context injection error when using injectStripe HoC #38

Closed
indiesquidge opened this issue Jul 17, 2017 · 5 comments
Closed

Getting context injection error when using injectStripe HoC #38

indiesquidge opened this issue Jul 17, 2017 · 5 comments

Comments

@indiesquidge
Copy link
Contributor

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!

@indiesquidge
Copy link
Contributor Author

indiesquidge commented Jul 17, 2017

So I think I figured out why the above code doesn't work.

Tl;dr

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

Details

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.

@michelle
Copy link
Collaborator

Awesome, I'm glad you figured it out :). That's exactly right. A PR for docs would be great!

@rdalfonso
Copy link

@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?

  1. Does react-stripe-elements handle the API call for making the payment for me using my test API key?
  2. Or do I need to take the token and do the API call myself using the token that's returned?

@atty-stripe
Copy link
Contributor

atty-stripe commented Jun 18, 2018

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

@rdalfonso
Copy link

@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!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants