如何为React-Stripe元素创建Usestripe钩



条纹具有反应条纹元素,可提供injectStripe HOC。我们在2019年,HOC不再酷。条纹似乎并不着急,我认为这是因为他们想支持较旧版本的react,因此仅查看最低的共同点解决方案。

我正在寻找一种通过钩子获得stripe的方法(而不是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挂钩? stripe应该与使用injectStripe Hook

相同

GH:API评论的相关问题:Hooks&amp;超越

经过一堆反复试验,我最终得到了这个,这很简单。在这里,条纹窥视和需要useStripe钩的其他人

// 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代码来查看发生了什么,但是您从injectStripe获得的stripe是您唯一可以使用的东西。您通过window.Stripe(apiKey)设置的一个并不相同,并且无法正常工作,因为它不正确地观察<Elements>,因此它不知道表单的状态。

也许,必须将injectStripe用于<Elements>的孩子的原因是Stripe Crew需要一段时间来构建此钩子的原因。

我自己做了,我已经为您准备了要点:(

useStripe挂钩使用useScript挂钩,其负责加载异步脚本(如Stripe One(。

这是要点:usecript.js

我已经简化了它,您可能也不需要语言环境。

这是用途:

import React from 'react'
let cache = []
const isCached = src => cache.includes(src)
export const useScript = src => {
  const [state, setState] = React.useState({
    isLoaded: isCached(src),
    hasError: false,
  })
  React.useEffect(() => {
    if (!src || isCached(src)) {
      return
    }
    cache.push(src)
    const script = document.createElement('script')
    script.src = src
    script.async = true
    const onScriptLoad = () => {
      setState(s => ({...s, isLoaded: true, hasError: false}))
    }
    const onScriptError = () => {
      const index = cache.indexOf(src)
      if (index >= 0) {
        cache.splice(index, 1)
      }
      script.remove()
      setState(s => ({...s, hasError: true, isLoaded: true}))
    }
    script.addEventListener('load', onScriptLoad)
    script.addEventListener('error', onScriptError)
    document.body.appendChild(script)
    return () => {
      script.removeEventListener('load', onScriptLoad)
      script.removeEventListener('error', onScriptError)
    }
  }, [src])
  return state
}

这是useStripe钩:

import React from 'react'
import {useScript} from './useScript'
let cache = {}
export const useStripe = ({locale, stripeKey}) => {
  const {isLoaded, error} = useScript('https://js.stripe.com/v3/')
  const [stripe, setStripe] = React.useState(cache[locale])
  React.useEffect(() => {
    if (isLoaded && !error && !cache[locale]) {
      cache[locale] = window.Stripe(stripeKey, {locale})
      setStripe(cache[locale])
    }
  }, [isLoaded, error, locale])
  return {
    stripe,
    error,
  }
}

这只是钩子,但是如果您需要上下文API,则可以将USEstripe代码移入提供商!

相关内容

  • 没有找到相关文章

最新更新