React.js集成Stripe报错:无法从指定Element获取数据,请确认Element已挂载
问题:Stripe与React.js集成时出现元素挂载相关错误
错误信息:
We could not retrieve data from the specified Element.Please make sure the Element you are attempting to use is still mounted.
中文翻译:无法从指定元素中获取数据,请确保你尝试使用的元素仍处于挂载状态。
相关代码片段
WithStripe 组件
// WithStripe Component import React from "react"; import { useSelector } from "react-redux"; import { Elements } from "@stripe/react-stripe-js"; import { loadStripe } from "@stripe/stripe-js"; function WithStripe({ children }) { const { stripeKey } = useSelector((state) => state?.stripeReducer); let promise = null; if (stripeKey) { promise = loadStripe(stripeKey); } const { language } = useSelector((state) => state?.AppReducer); return ( <Elements stripe={promise} options={{ locale: language, }} > {children} </Elements> ); } export default WithStripe;
入口文件
// Entry point import React, { Suspense } from "react"; import ReactDOM from "react-dom"; import "./index.css"; import App from "./app/Index"; import WithStripe from "components/Hoc/WithStripe"; ReactDOM.render( <WithStripe> <App /> </WithStripe>, document.getElementById("root") );
解决方案
确保Stripe实例加载完成后再渲染子组件:当前代码中
stripeKey为空时,promise会是null,直接传给Elements会导致子组件内的Stripe元素无法正常初始化。可以添加条件渲染,仅在stripeKey存在时渲染Elements,或添加加载状态:function WithStripe({ children }) { const { stripeKey } = useSelector((state) => state?.stripeReducer); const { language } = useSelector((state) => state?.AppReducer); if (!stripeKey) { return <div>Loading Stripe...</div>; } const stripePromise = loadStripe(stripeKey); return ( <Elements stripe={stripePromise} options={{ locale: language }} > {children} </Elements> ); }检查Redux中stripeKey的初始化时机:确认
stripeReducer是否在组件挂载前就已加载有效的Stripe公钥。如果stripeKey是异步获取的,要确保拿到密钥后再渲染依赖Stripe的组件,避免元素在Stripe实例准备好前就被挂载。子组件中添加Stripe实例加载判断:在使用Stripe Elements(如CardElement)的子组件里,通过
useStripe()和useElements()钩子检查实例是否存在,再渲染对应元素:import { useStripe, useElements, CardElement } from "@stripe/react-stripe-js"; function PaymentForm() { const stripe = useStripe(); const elements = useElements(); if (!stripe || !elements) { return <div>Loading payment form...</div>; } return ( <form> <CardElement /> {/* 其他表单元素 */} </form> ); }
内容的提问来源于stack exchange,提问作者Khan Naxim
相关产品推荐
相关产品推荐

