如何在React组件中正确引入Teller.io脚本并调用其暴露的TellerConnect方法
React 项目引入 Teller.io 脚本的规范实现方案
核心优化逻辑
- 监听脚本加载完成事件后再执行初始化,避免异步脚本未加载完毕时调用全局方法报错
- 移除原生DOM事件监听操作,改用React原生事件机制,符合React开发范式
- 补充useEffect清理逻辑,避免组件卸载时出现内存泄漏
- 支持TypeScript类型声明,解决全局属性无法识别的问题
基础优化实现
import { useEffect, useCallback, useRef, useState } from 'react'; function TellerConnectButton() { const tellerInstanceRef = useRef(null); const [scriptLoaded, setScriptLoaded] = useState(false); // 初始化Teller Connect const initTeller = useCallback(() => { if (!window.TellerConnect) return; tellerInstanceRef.current = window.TellerConnect.setup({ applicationId: "Your application ID e.g app_xxxxxx", onInit: () => { console.log("Teller Connect has initialized"); }, onSuccess: (enrollment) => { console.log("User enrolled successfully", enrollment.accessToken); }, onExit: () => { console.log("User closed Teller Connect"); } }); }, []); // 打开Teller认证弹窗 const handleOpenConnect = useCallback(() => { tellerInstanceRef.current?.open(); }, []); useEffect(() => { // 避免重复加载脚本 if (window.TellerConnect) { setScriptLoaded(true); initTeller(); return; } const script = document.createElement("script"); script.src = "https://cdn.teller.io/connect/connect.js"; script.async = true; // 脚本加载完成后执行初始化 script.onload = () => { setScriptLoaded(true); initTeller(); }; // 脚本加载失败处理 script.onerror = () => { console.error("Teller Connect 脚本加载失败"); }; document.head.appendChild(script); // 组件卸载清理逻辑 return () => { // 移除脚本 if (document.head.contains(script)) { document.head.removeChild(script); } // 销毁Teller实例避免内存泄漏 tellerInstanceRef.current = null; }; }, [initTeller]); return ( <button onClick={handleOpenConnect} disabled={!scriptLoaded}> 关联银行账户 </button> ); }
TypeScript 类型补充
如果你的项目使用TypeScript,可在全局类型声明文件中添加以下内容,解决window.TellerConnect不存在的类型报错:
declare global { interface Window { TellerConnect: { setup: (config: { applicationId: string; onInit?: () => void; onSuccess?: (enrollment: { accessToken: string; [key: string]: any }) => void; onExit?: () => void; [key: string]: any; }) => { open: () => void; [key: string]: any; }; }; } } export {};
可复用自定义Hook封装
如果多个组件需要用到Teller Connect能力,可以封装为自定义Hook提升复用性:
import { useEffect, useCallback, useRef, useState } from 'react'; function useTellerConnect(config) { const tellerInstanceRef = useRef(null); const [isReady, setIsReady] = useState(false); useEffect(() => { const init = () => { tellerInstanceRef.current = window.TellerConnect.setup(config); setIsReady(true); }; if (window.TellerConnect) { init(); return; } const script = document.createElement("script"); script.src = "https://cdn.teller.io/connect/connect.js"; script.async = true; script.onload = init; script.onerror = () => console.error("Teller脚本加载失败"); document.head.appendChild(script); return () => { if (document.head.contains(script)) { document.head.removeChild(script); } tellerInstanceRef.current = null; }; }, [config]); const open = useCallback(() => { tellerInstanceRef.current?.open(); }, []); return { open, isReady }; } // 组件内使用示例 function MyComponent() { const { open, isReady } = useTellerConnect({ applicationId: "app_xxxxxx", onSuccess: (enrollment) => console.log(enrollment.accessToken) }); return <button onClick={open} disabled={!isReady}>关联账户</button> }
内容的提问来源于stack exchange,提问作者Aluxxen
相关产品推荐
相关产品推荐

