Stripe具有react-stripe-elements,提供injectStripe
HOC。我们现在在2019年,而HOC不再那么酷了。 Stripe似乎并不着急,我认为这是因为他们想支持旧版本的React,因此只在寻找最低的公分母解决方案。
我正在寻找一种通过 Hook (而不是stripe
提供的 Prop )获取injectStripe
的方法。
用法看起来像这样const stripe = useStripe()
这样以后我就可以使用stripe.handleCardSetup
和其他API方法
import { CardElement } from 'react-stripe-elements'
const CardForm = ({secret}) => {
const stripe = useStripe()
const handleSubmit = async () => {
const { setupIntent, error } = await stripe.handleCardSetup(secret)
// ...
}
return (
<>
<CardElement />
<button onClick={handleSubmit} />
</>
)
}
您如何从现有的API和组件中定义
useStripe
Hook ?stripe
应该与使用injectStripe
钩子(Hook)时获得的内容相同GH的相关问题:API Review: Hooks & Beyond
最佳答案
经过一堆反复试验后,我得出了这个结论,这很简单。这是采用条纹偷看和其他需要useStripe
钩子(Hook)的人
// StripeHookProvider.jsx
import React, { useContext, createContext } from 'react'
import { injectStripe } from 'react-stripe-elements'
const Context = createContext()
export const useStripe = () => useContext(Context)
const HookProvider = ({ children, stripe }) => {
return <Context.Provider value={stripe}>{children}</Context.Provider>
}
export default injectStripe(HookProvider)
像这样导入
StripeHookProvider
并将其添加到您的组件层次结构中。注意:因为它依赖injectStripe
,所以它必须是<Elements>
的子级 <StripeProvider {...{ stripe }}>
<Elements>
<StripeHookProvider>
<MyForm />
</StripeHookProvider>
</Elements>
</StripeProvider>
然后在MyForm中使用它像这样
// MyForm.jsx
import { useStripe } from './StripeHookProvider'
const MyForm = () => {
const stripe = useStripe()
const handleSubmit = () => {
const { setupIntent, error } = await stripe.handleCardSetup(secret ... // and so on
}
}
这样,您只需要在一个地方进行
injectStripe
即可,并且将其整齐地藏在视线之外。从该代码中可以看到,这不是火箭科学,对于条纹偷看者来说,将其添加到他们的代码中应该不是问题,因为它们在上下文中的某个地方对<StripeHookProvider>
对象的引用,因此希望完全消除stripe
。我尝试了很多方法,但这是唯一可行的方法。我没有深入研究Stripe的JS代码来了解发生了什么,但是唯一可以使用的是从
stripe
获得的injectStripe
。您通过window.Stripe(apiKey)
设置的代码不相同,并且由于无法正确观察<Elements>
而无法正常工作,因此它不知道表单的状态。也许,必须在
injectStripe
的子级上使用<Elements>
的原因与Stripe团队花一些时间来构建此 Hook 的原因相同。